Skip to content

15. NaughtCoin

r1oga edited this page Oct 29, 2022 · 2 revisions

Target

Transfer your naughtcoins to another address.**

Weakness

NaughCoin inherits from the ERC20 contract. Looking at this contract, we notice that transfer() is not the only function to transfer tokens.
Indeed transferFrom(address sender, address recipient, uint256 amount) can be used instead: provided that a 3rd user (spender) was allowed beforehand by the owner of the tokens to spend a given amount of the total owner's balance, spender can transfer amount to recipient in the name of owner.
Successfully executing transferFrom requires the caller to have allowance for sender's tokens of at least amount. The allowance can be set with the approve or increaseAllowance functions inherited from ERC20.

Concepts

The ERC20 token contract is related to the EIP 20 - ERC20 token standard. It is the most widespread token standard for fungible assets.

Any one token is exactly equal to any other token; no tokens have special rights or behavior associated with them. This makes ERC20 tokens useful for things like a medium of exchange currency, voting rights, staking, and more.

Architecture
transferFrom calls _transfer and _approve. _approve calls allowance and checks whether the caller was allowed to spend the amount by sender.

architecture diagram

Hack

We want to set the player's allowance for the attack contract. For this we need to callapprove() which calls _approve(msg.sender, spender, amount). In this call we need msg.sender == player, so we can't call victim.approve() from the attacker contract. If we would, then msg.sender == attackerContractAddress. This would set the attacker contract's allowance instead of the player's one. So we call victim.approve() directly from the player's address. Finally we let the attacker call transferFrom() to transfer to itself the player's tokens.

Hack workflow diagram

Note: the same can be achieved by simply approving another EOA instead of of a deployed attacker contract (see NaughtCoin.t.sol).

Security Takeaways

Get familiar with contracts you didn't write, especially with imported and inherited contracts. Check how they implement authorization controls.

Clone this wiki locally