Amun contest - gpersoon'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: 10/30

Findings: 3

Award: $2,657.56

🌟 Selected for report: 3

🚀 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

gpersoon

Vulnerability details

Impact

The function joinPool() tries to prevent going over the cap by checking:

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

However later on in the code, 2 mint actions take place (which increase the totalSupply). One is for "feeBeneficiaryShare" and the other is for "_amount". These 2 together are more than "_amount", so if the supply is close to the Cap it could slightly surpass the Cap, with feeBeneficiaryShare

Proof of Concept

https://github.com/code-423n4/2021-12-amun/blob/cf890dedf2e43ec787e8e5df65726316fda134a1/contracts/basket/contracts/facets/Basket/BasketFacet.sol#L143-L185

function joinPool(uint256 _amount, uint16 _referral)  external  override  noReentry  {
      ...
        require(  totalSupply.add(_amount) <= this.getCap(),   "MAX_POOL_CAP_REACHED"  );
         ....
            if (feeBeneficiaryShare != 0) {
                LibERC20.mint(bs.feeBeneficiary, feeBeneficiaryShare);  // mint an additional feeBeneficiaryShare
            }
        ....
        LibERC20.mint(msg.sender, _amount);         // mints _amount

Tools Used

Move the require statement to the end of function joinPool() and change it to:

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

If this require doesn't succeed is will roll back all actions. Note: it will use slightly more gas when the Cap is reached and a revert takes place

#0 - loki-sama

2022-01-03T11:29:56Z

Duplicate #283

Findings Information

🌟 Selected for report: gpersoon

Also found by: kenzo, robee

Labels

bug
2 (Med Risk)

Awards

811.1888 USDC - $811.19

External Links

Handle

gpersoon

Vulnerability details

Impact

Some functions, like rebalance() in RebalanceManagerV3 use _deadline as a time limit for swapExactTokensForTokens() Other functions, like _joinTokenSingle() of SingleTokenJoinV2.sol and _exit() of SingleNativeTokenExitV2() use block.timestamp, although a deadline field is present in the struct.

Possibly the deadline fields should have been used.

Proof of Concept

https://github.com/code-423n4/2021-12-amun/blob/cf890dedf2e43ec787e8e5df65726316fda134a1/contracts/basket/contracts/callManagers/RebalanceManagerV3.sol#L158-L203

function rebalance(UnderlyingTrade[] calldata _swapsV2, uint256 _deadline)  external override onlyRebalanceManager {
...
        for (uint256 i; i < _swapsV2.length; i++) {
  ...
            for (uint256 j; j < trade.swaps.length; j++) {
                ..
                _swapUniswapV2(swap.exchange,input,0, swap.path,address(basket), _deadline );

https://github.com/code-423n4/2021-12-amun/blob/cf890dedf2e43ec787e8e5df65726316fda134a1/contracts/basket/contracts/callManagers/RebalanceManagerV3.sol#L63-L104

function _swapUniswapV2(...) {
        basket.singleCall(
            exchange,
            abi.encodeWithSelector(  IUniswapV2Router02(exchange).swapExactTokensForTokens.selector,  quantity,   minReturn,  path, recipient, deadline  ),
            0
        );

https://github.com/code-423n4/2021-12-amun/blob/cf890dedf2e43ec787e8e5df65726316fda134a1/contracts/basket/contracts/singleJoinExit/SingleTokenJoinV2.sol#L80-L112

struct JoinTokenStructV2 {
     ...
        uint256 deadline;
     ...
    }
function _joinTokenSingle(JoinTokenStructV2 calldata _joinTokenStruct)  internal {
     ...
           for (uint256 j; j < trade.swaps.length; j++) {
                IPangolinRouter(swap.exchange).swapExactTokensForTokens( amountIn,  0, swap.path, address(this),  block.timestamp );
            }
        }

https://github.com/code-423n4/2021-12-amun/blob/cf890dedf2e43ec787e8e5df65726316fda134a1/contracts/basket/contracts/singleJoinExit/SingleNativeTokenExitV2.sol#L59-L88

 struct ExitTokenStructV2 {
        ...
        uint256 deadline;
       ...
    }
function _exit(ExitTokenStructV2 calldata _exitTokenStruct) internal {
     ...
        for (uint256 i; i < _exitTokenStruct.trades.length; i++) {
           ...
            for (uint256 j; j < trade.swaps.length; j++) {
                ...
                IPangolinRouter(swap.exchange).swapExactTokensForTokens( IERC20(swap.path[0]).balanceOf(address(this)), 0, swap.path, address(this), block.timestamp );
            }
        }

Tools Used

Check whether the deadline fields should have been used. If so replace block.timestamp with the appropriate deadline

#0 - loki-sama

2022-01-04T11:12:34Z

duplicate #47

#1 - 0xleastwood

2022-01-22T03:57:17Z

Marking as primary issue.

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