Amun contest - certora'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: 3/30

Findings: 4

Award: $8,587.28

🌟 Selected for report: 4

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: pmerkleplant

Also found by: WatchPug, certora, hyh, p4st13r4, pauliax, robee

Labels

bug
duplicate
2 (Med Risk)

Awards

228.0947 USDC - $228.09

External Links

Handle

certora

Vulnerability details

https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoin.sol#L135 the balance of outputToken is checked to be exactly _joinTokenStruct.outputAmount.
It is not recommeded and it's better to use >=

Impact

The worst scenario is a denial of service in case there is already an amount of the output token in the contract. It is easily achieved by transferring tokens to the contract. then it will lead to denial of service of joinTokenSingle because the actual balance at the end of the function will be greater than _joinTokenStruct.outputAmount so the transaction would revert.

Proof of concept

An attacker can transfer basket tokens to SingleTokenJoin contract, after that, no one will be able to use it. Let's assume the attacker transferred one basket token, then a users tries to use joinTokenSingle. in the following line, the basket will send _joinTokenStruct.outputAmount to address(this): https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L122 after that, outputToken.balanceOf(address(this)) will be _joinTokenStruct.outputAmount + 1. because the attacker transferred one token. therefore the require statement will fail and the transaction will revert:

uint256 outputAmount = outputToken.balanceOf(address(this)); require( outputAmount == _joinTokenStruct.outputAmount, "FAILED_OUTPUT_AMOUNT" );

this can never be changed and the contract will stay in a state of denial of service forever.

change to

require( outputAmount >= _joinTokenStruct.outputAmount, "FAILED_OUTPUT_AMOUNT" );

This issue is also in: https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L130

#0 - loki-sama

2022-01-03T09:28:52Z

duplicate #81

Findings Information

🌟 Selected for report: JMukesh

Also found by: certora

Labels

bug
duplicate
2 (Med Risk)

Awards

1351.9814 USDC - $1,351.98

External Links

Handle

certora

Vulnerability details

https://github.com/code-423n4/2021-12-amun/blob/main/contracts/basket/contracts/singleJoinExit/EthSingleTokenJoin.sol#L26

there is no check on the return value of call.

(bool success, ) = address(INTERMEDIATE_TOKEN).call{value: msg.value}(""); require(success);

#0 - 0xleastwood

2022-01-23T04:57:13Z

Duplicate of #237

Findings Information

🌟 Selected for report: certora

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

3004.4031 USDC - $3,004.40

External Links

Handle

certora

Vulnerability details

after that fee is calculated, it is minted to the feeBeneficiary. simply minting the exact amount results lower fee than it should be.

Impact

feeBeneficiary will get less fees than it should.

Proof of Concept

let's assume that the basket assets are worth 1M dollars, and totalSupply = 1M. the result of calcOutStandingAnnualizedFee is 100,00 so the feeBeneficiary should get 100,00 dollars. however, when minting 100,00 the totalSupply will increase to 1,100,000 so they will own 100000/1100000* (1M dollars) = 90909.09 dollars instead of 100k

#0 - loki-sama

2022-01-04T10:53:29Z

This is mitigated by the feeBeneficiary diluting his own shares if he gets fees on his fees.

#1 - 0xleastwood

2022-01-23T02:07:11Z

I'm not exactly sure if I understand what the warden is stating here. Could you confirm @loki-sama ?

#2 - loki-sama

2022-01-24T14:08:36Z

Ok, I myself misunderstood. He is correct that we don't get the full value. When we take a fee of 10% like from his example. What we do is mint 10% of the basket to ourselves. That 10% after minting is not holding 10% of the underling.

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