Backd Tokenomics contest - berndartmueller's results

Maximize the power of your assets and start earning yield

General Information

Platform: Code4rena

Start Date: 27/05/2022

Pot Size: $75,000 USDC

Total HM: 20

Participants: 58

Period: 7 days

Judge: GalloDaSballo

Total Solo HM: 15

Id: 131

League: ETH

Backd

Findings Distribution

Researcher Performance

Rank: 21/58

Findings: 2

Award: $352.96

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

268.1375 USDC - $268.14

Labels

bug
QA (Quality Assurance)
sponsor disputed

External Links

Lines of code

https://github.com/code-423n4/2022-05-backd/blob/2a5664d35cde5b036074edef3c1369b984d10010/protocol/contracts/tokenomics/FeeBurner.sol#L70

Vulnerability details

Impact

There are ERC20 tokens that may make certain customizations to their ERC20 contracts. One type of these tokens is deflationary tokens that charge a certain fee for every transfer() or transferFrom().

Proof of Concept

The FeeBurner.burnToTarget function will try to swap more of an ERC20 token than the contract actually received and due to transfering the token into the SwapperRouter contract, the token balance is insufficient and the transfer will revert.

tokenomics/FeeBurner.sol#L70

token_.safeTransferFrom(msg.sender, address(this), tokenBalance_); // @audit-info less tokens will be received in the contract when using fee-on transfer tokens
if (address(token_) == targetUnderlying_) continue;
_approve(address(token_), address(swapperRouter_));
swapperRouter_.swap(address(token_), _WETH, tokenBalance_); // @audit-info the swap function transfers the `token_` to itself and due to `tokenBalance_` not reflecting the correct token amount in the contract, the swap will revert

Tools Used

Manual review

As other contracts (e.g. AmmGauge.stakeFor) already handle fee-on transfer tokens correctly, make sure also FeeBurner.burnToTarget does so.

Compare the token balance before the transfer and after the transfer and use the delta as the actual swap amount to prevent the FeeBurner.burnToTarget function reverting for fee-on transfer tokens:

function burnToTarget(address[] memory tokens_, address targetLpToken_)
    public
    payable
    override
    returns (uint256 received)
{
    ...

    uint256 oldBal = token_.balanceOf(address(this));
    token_.safeTransferFrom(msg.sender, address(this), tokenBalance_);
    uint256 swapAmount = token_.balanceOf(address(this)) - oldBal;

    if (address(token_) == targetUnderlying_) continue;
    _approve(address(token_), address(swapperRouter_));
    swapperRouter_.swap(address(token_), _WETH, swapAmount); // @audit-info use `swapAmount`

    ...
}

#0 - chase-manning

2022-06-06T11:27:52Z

We don't support fee-on-transfer tokens

#1 - GalloDaSballo

2022-06-19T21:16:06Z

I believe that the finding has validity, however in case of a revert, no funds would be loss nor stuck, for that reason QA is a more appropriate Severity

Awards

84.8218 USDC - $84.82

Labels

bug
G (Gas Optimization)
resolved
sponsor confirmed

External Links

[G-01] Unnecessary check for positive value

Description

A uint256 value can not be negative, hence there is no need to check for it.

Findings

tokenomics/InflationManager.sol#L589

totalLpPoolWeight = totalLpPoolWeight > 0 ? totalLpPoolWeight : 0;

tokenomics/InflationManager.sol#L602

totalAmmTokenWeight = totalAmmTokenWeight > 0 ? totalAmmTokenWeight : 0;

tokenomics/InflationManager.sol#L575

totalKeeperPoolWeight = totalKeeperPoolWeight > 0 ? totalKeeperPoolWeight : 0;

Remove the check and use the value directly to save gas.

[G-02] Unnecessary poolCheckpoint function call

The AmmGauge and KeeperGauge contracts call the function poolCheckpoint() within the kill() function. Therefore, functions which call this kill() function do not have to additionally call the poolCheckpoint() function.

Description

A uint256 value can not be negative, hence there is no need to check for it.

Findings

tokenomics/InflationManager.sol#L427
tokenomics/InflationManager.sol#L461

Remove the call to poolCheckpoint() to save gas.

#0 - GalloDaSballo

2022-06-17T23:21:49Z

[G-01] Unnecessary check for positive value

I agree, because these are Storage value set to the same value, the gas saved is 100 per instance 300

[G-02] Unnecessary poolCheckpoint function call

I agree, but would have liked to see a POC with detailed gas savings, in lack of it will give it 200 gas (low estimate)

Total Gas Saved

500

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