Amun contest - kenzo'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: 6/30

Findings: 5

Award: $3,426.19

🌟 Selected for report: 5

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Czar102

Also found by: WatchPug, gpersoon, gzeon, kenzo

Labels

bug
duplicate
2 (Med Risk)

Awards

394.2378 USDC - $394.24

External Links

Handle

kenzo

Vulnerability details

When joining a basket, the function verifies that the total supply + tokens the user asks to mint is smaller than the basket's max supply. However, this doesn't take into account the fact that additional tokens will be minted if there's an entry fee beneficiary share.

Impact

More tokens will be minted than basket's max cap.

Proof of Concept

Upon user entering the pool, joinPool will check that the requested amount does not surpass the basket's max cap: (Code ref)

require( totalSupply.add(_amount) <= this.getCap(), "MAX_POOL_CAP_REACHED");

It will mint _amount to the user: (Code ref)

LibERC20.mint(msg.sender, _amount);

And if there's a beneficiary share of the entry fee, it will mint additional tokens to the beneficiary: (Code ref)

LibERC20.mint(bs.feeBeneficiary, feeBeneficiaryShare);

These tokens were not checked against the token's maxCap and therefore it can go over the limit.

Add the feeBeneficiaryShare to the check against maxCap.

#0 - loki-sama

2021-12-29T11:43:55Z

Duplicate #283

Findings Information

🌟 Selected for report: gpersoon

Also found by: kenzo, robee

Labels

bug
duplicate
2 (Med Risk)

Awards

811.1888 USDC - $811.19

External Links

Handle

kenzo

Vulnerability details

SingleNativeTokenExitV2 takes as input from the user a deadline for the trades. However, it does not use this input for the actual trade but sets the deadline to be block.timestamp.

Impact

Trades will not work as expected. User might set a deadline for the trade but his trade will get executed regardless.

Duplicate issue?

This issue is present in a few contracts in the repo - SingleNativeTokenExitV2, SingleTokenJoinV2. If I submit both in one issue, but the judge will decide to reward them separately, he would not be able to do so for me as I submitted them all in one issue. So this is why I am submitting them in separate issues. If it is will be rewarded only as one issue, the judge will close the duplicate. Thank you.

Proof of Concept

We can see the input struct has deadline as a parameter, however, _exit passes as deadline block.timestamp, and not the input deadline.

Send to the router _exitTokenStruct.deadline instead of block.timestamp. (Code ref)

#0 - loki-sama

2021-12-29T12:44:36Z

duplicate #112

#1 - 0xleastwood

2022-01-22T03:58:43Z

Duplicate of #47

Findings Information

🌟 Selected for report: kenzo

Also found by: cmichel, hyh

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

811.1888 USDC - $811.19

External Links

Handle

kenzo

Vulnerability details

SingleNativeTokenExitV2 allows the user to exit and execute trades via multiple exchanges. When finishing the trades and sending a single output token back to the user, the contract takes that token from the last swap in the first exchange's trades. There is nothing in the struct that signifies this will be the output token, and this also impairs the exit functionality.

Impact

Let's say a basket only holds token TOKE, and user would like to exit to DAI. But there's no exchange with good liquidity for TOKE -> DAI. So the user crafts a trade to exchange TOKE for WOKE in exchange A, and then exchange WOKE for DAI in exchange B, to finally receive back DAI. The contract will not let him do so, as the output token is taken to be the output token of the first exchange - WOKE in our example.

Proof of Concept

In exit, the output token is taken to be the last token exchanged in the first exchange: (Code ref)

address[] calldata path = _exitTokenStruct .trades[0] .swaps[_exitTokenStruct.trades[0].swaps.length - 1] .path; IERC20 outputToken = IERC20(path[path.length - 1]); //this could be not the target token

This manifests the issue I detailed above.

Have the outputToken be a parameter supplied in ExitTokenStructV2.

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