Lucene search

K
code423n4Code4renaCODE423N4:2022-05-VELODROME-FINDINGS-ISSUES-144
HistoryMay 30, 2022 - 12:00 a.m.

functions deposit() and notifyRewardAmount() in Bribe and Gauge contract don't consider deflationary tokens when transferring

2022-05-3000:00:00
Code4rena
github.com
8
bribe contract
gauge contract
deflationary tokens

Lines of code
<https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L664-L676&gt;
<https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Bribe.sol#L41-L60&gt;
<https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L511-L520&gt;
<https://github.com/code-423n4/2022-05-velodrome/blob/7fda97c570b758bbfa7dd6724a336c43d4041740/contracts/contracts/Gauge.sol#L603-L612&gt;

Vulnerability details

Impact

The actual amount that has been transferred can be different than requested amount in deflationary tokens and this is not been addressed in transferring logic in the code. This can cause wrong calculation and rewards distribution for users.

Proof of Concept

This is deposit() code in Gauge:

    function deposit(uint amount, uint tokenId) public lock {
        require(amount &gt; 0);

        _updateRewardForAllTokens();

        _safeTransferFrom(stake, msg.sender, address(this), amount);
        totalSupply += amount;
        balanceOf[msg.sender] += amount;

        if (tokenId &gt; 0) {
            require(IVotingEscrow(_ve).ownerOf(tokenId) == msg.sender);
            if (tokenIds[msg.sender] == 0) {
                tokenIds[msg.sender] = tokenId;
                IVoter(voter).attachTokenToGauge(tokenId, msg.sender);
            }
            require(tokenIds[msg.sender] == tokenId);
        } else {
            tokenId = tokenIds[msg.sender];
        }

        uint _derivedBalance = derivedBalances[msg.sender];
        derivedSupply -= _derivedBalance;
        _derivedBalance = derivedBalance(msg.sender);
        derivedBalances[msg.sender] = _derivedBalance;
        derivedSupply += _derivedBalance;

        _writeCheckpoint(msg.sender, _derivedBalance);
        _writeSupplyCheckpoint();

        IVoter(voter).emitDeposit(tokenId, msg.sender, amount);
        emit Deposit(msg.sender, tokenId, amount);
    }

As you can see it calls _safeTransferFrom(stake, msg.sender, address(this), amount); to get user tokens and then it adds amount to user balance and total supply: totalSupply += amount; balanceOf[msg.sender] += amount; but the actual transferred amount could be different in deflationary tokens and this can cause wrong reward distributions.
The other instances of the bug are similar.

Tools Used

VIM

Recommended Mitigation Steps

check for actual transferred amount when transferring.


The text was updated successfully, but these errors were encountered:

All reactions