Amun contest - cmichel's results

We build tokens to make it easy to invest in crypto.

General Information

Platform: Code4rena

Start Date: 13/12/2021

Pot Size: $75,000 USDC

Total HM: 11

Participants: 30

Period: 7 days

Judge: leastwood

Total Solo HM: 4

Id: 68

League: ETH

Amun

Findings Distribution

Researcher Performance

Rank: 5/30

Findings: 4

Award: $4,412.08

🌟 Selected for report: 8

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: cmichel

Also found by: JMukesh, WatchPug, defsec, p4st13r4

Labels

bug
2 (Med Risk)

Awards

394.2378 USDC - $394.24

External Links

Handle

cmichel

Vulnerability details

The ERC20.transfer() and ERC20.transferFrom() functions return a boolean value indicating success. This parameter needs to be checked for success. Some tokens do not revert if the transfer failed but return false instead.

See:

  • SingleNativeTokenExitV2.exit's outputToken.transfer(msg.sender, outputTokenBalance);
  • PieFactoryContract.bakePie's pie.transfer(msg.sender, _initialSupply);

Impact

Tokens that don't actually perform the transfer and return false are still counted as a correct transfer and the tokens remain in the SingleNativeTokenExitV2 contract and could potentially be stolen by someone else.

We recommend using OpenZeppelin’s SafeERC20 versions with the safeTransfer and safeTransferFrom functions that handle the return value check as well as non-standard-compliant tokens.

#0 - loki-sama

2022-01-04T10:29:21Z

duplicate #232

#1 - 0xleastwood

2022-01-22T04:08:21Z

Marking as primary issue.

#2 - 0xleastwood

2022-01-22T04:09:48Z

Nice find! I think this is valid considering the extent basket tokens are used. It is more than likely that non-standard tokens will be utilised.

Findings Information

🌟 Selected for report: kenzo

Also found by: cmichel, hyh

Labels

bug
duplicate
2 (Med Risk)

Awards

811.1888 USDC - $811.19

External Links

Handle

cmichel

Vulnerability details

The SingleNativeTokenExitV2.exit function performs a list of arbitrary user-defined swaps on the exited token basket. These could result in many different final "output" tokens ending up in the contract after the swaps. However, the contract assumes that there's only a single outputToken, more specifically, the last path token of the last swap of the first trade:

function exit(ExitTokenStructV2 calldata _exitTokenStruct) external {
    _exit(_exitTokenStruct);
    address[] calldata path = _exitTokenStruct
        .trades[0]
        .swaps[_exitTokenStruct.trades[0].swaps.length - 1]
        .path;
    // @audit why only pay out the last path token of the last swap of the first trade? non-intuitive, should be documented
    IERC20 outputToken = IERC20(path[path.length - 1]); //this could be not the target token
    // ...
}

Impact

The single output token that is decided to be paid out seems quite arbitrary and it's non-intuitive and not documented for any caller trying to exit their position through this contract.

Iterate through all the tokens of the basket and pay out all of them if there's a balance in the contract after the trades.

#0 - loki-sama

2022-01-04T10:28:14Z

The swaps should all be going to one token so this could be improved

#1 - loki-sama

2022-01-05T17:32:58Z

duplicate #176

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter