Amun contest - pauliax'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: 13/30

Findings: 3

Award: $1,141.51

🌟 Selected for report: 5

🚀 Solo Findings: 0

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

pauliax

Vulnerability details

Impact

Token join contracts check that the final outputAmount is equal to _joinTokenStruct.outputAmount:

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

While these contracts are only for convenience, a theoretical attack exists here: a malicious actor can monitor the mempool and send the smallest fraction of the output token (basket) directly to the contract thus breaking this check.

Consider replacing == with >= .

#0 - loki-sama

2022-01-03T09:29:18Z

duplicate #81

Findings Information

🌟 Selected for report: GiveMeTestEther

Also found by: JMukesh, Ruhum, WatchPug, certora, cmichel, kenzo, p4st13r4, pauliax, robee

Labels

bug
duplicate
1 (Low Risk)

Awards

38.7989 USDC - $38.80

External Links

Handle

pauliax

Vulnerability details

Impact

.transfer usage is discouraged and is no longer recommended as recipients with custom fallback functions (smart contracts) will not be able to handle that. You can read more here: https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/

Solution (don't forget re-entrancy protection): https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L53-L59

#0 - loki-sama

2022-01-03T10:01:36Z

#175

Findings Information

🌟 Selected for report: pauliax

Also found by: GiveMeTestEther, itsmeSTYJ, robee

Labels

bug
1 (Low Risk)

Awards

182.5175 USDC - $182.52

External Links

Handle

pauliax

Vulnerability details

Impact

Rebalance managers approve max if allowance < quantity. SingleTokenJoin, SingleTokenJoinV2, SingleNativeTokenExit, and SingleNativeTokenExitV2. approve max if allowance < balance.

The problem is that some tokens, e.g. USDT require resetting approval to 0 before approving any value again.

Consider using this approach:

  token.approve(spender, 0);
  token.approve(spender, uint256(-1));

Findings Information

🌟 Selected for report: pauliax

Also found by: certora

Labels

bug
1 (Low Risk)
sponsor confirmed

Awards

450.6605 USDC - $450.66

External Links

Handle

pauliax

Vulnerability details

Impact

I am sorry if I incorrectly understood the intentions of contract PolygonERC20Wrapper but the comments and the code do not align here:

Function deposit: "Should handle deposit by minting the required amount for user. Make sure minting is done only by this function". However, the code does not perform any minting and just transfers the underlying tokens to the user.

On the other hand, functions withdraw and withdrawTo state: "Should burn user's tokens" but it actually performs both, minting and burning:

  _mint(recipient, amount);
  _burn(recipient, amount);

I was late to verify this with the sponsor, so make sure this is the intended behavior, and update comments to match the codebase.

#0 - loki-sama

2021-12-30T13:53:51Z

The behavior is as intended. Maybe can change the comments.

Findings Information

🌟 Selected for report: Dravee

Also found by: gzeon, kenzo, pauliax

Labels

bug
duplicate
G (Gas Optimization)

Awards

14.2759 USDC - $14.28

External Links

Handle

pauliax

Vulnerability details

Impact

Assigned operations to constant variables are re-evaluated every time:

  bytes32 constant BASKET_STORAGE_POSITION =
        keccak256("diamond.standard.basket.storage");
  bytes32 constant CALL_STORAGE_POSITION =
        keccak256("diamond.standard.call.storage");
  bytes32 constant REENTRY_STORAGE_POSITION =
        keccak256("diamond.standard.reentry.storage");
  bytes32 constant ERC_20_STORAGE_POSITION =
        keccak256(
            // Compatible with pie-smart-pools
            "PCToken.storage.location"
        );

See https://github.com/ethereum/solidity/issues/9232

Change from 'constant' to 'immutable'.

#0 - 0xleastwood

2022-01-24T09:54:29Z

Duplicate of #281

Findings Information

🌟 Selected for report: WatchPug

Also found by: pauliax

Labels

bug
duplicate
G (Gas Optimization)
sponsor confirmed

Awards

35.2492 USDC - $35.25

External Links

Handle

pauliax

Vulnerability details

Impact

_amount.add(feeAmount) is re-evaluated again and again inside the loop:

  for (uint256 i; i < bs.tokens.length; i++) {
     ...
      uint256 tokenAmount =
          balance(address(token)).mul(_amount.add(feeAmount)).div(
              totalSupply
          );
     ...
  }

These values do not change so consider extracting outside the loop to reduce gas costs.

#0 - 0xleastwood

2022-01-24T09:56:06Z

Duplicate of #205

Findings Information

🌟 Selected for report: pauliax

Also found by: kenzo

Labels

bug
G (Gas Optimization)
sponsor confirmed

Awards

35.2492 USDC - $35.25

External Links

Handle

pauliax

Vulnerability details

Impact

Contracts SingleTokenJoinV2 and SingleNativeTokenExitV2 initialize uniSwapLikeRouter, but never actually use it, as swap.exchange is used instead. So it basically trusts the user input. Consider removing uniSwapLikeRouter if that was the intention to save some gas.

Findings Information

🌟 Selected for report: pauliax

Labels

bug
G (Gas Optimization)
sponsor acknowledged

Awards

78.3316 USDC - $78.33

External Links

Handle

pauliax

Vulnerability details

Impact

structs can be optimized, e.g. inputAmount and outputAmount could be stored in uint112, as that is what Uniswap like exchanges use: https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L22-L23

'deadline' also usually fits in a reasonable limit of at least uint32 or uint64. 'entryFee', 'exitFee', etc are also capped, so you should consider revisiting structs to find optimal sizes and orders of the variables.

Findings Information

🌟 Selected for report: pauliax

Labels

bug
G (Gas Optimization)
sponsor disputed

Awards

78.3316 USDC - $78.33

External Links

Handle

pauliax

Vulnerability details

Impact

Not used state variables:

  bool private recovered;
  bool private burned;

Consider removing them to reduce deployment costs.

#0 - 0xleastwood

2022-01-24T09:53:53Z

As far as I can see, the warden is correct. So keeping this open

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