Lucene search

K
code423n4Code4renaCODE423N4:2023-07-RESERVE-FINDINGS-ISSUES-12
HistoryAug 03, 2023 - 12:00 a.m.

StaticATokenLM transfer missing _updateRewards

2023-08-0300:00:00
Code4rena
github.com
1
staticatokenlm
updaterewards
loss
imbalance
mitigation
beforetokentransfer

AI Score

7

Confidence

Low

Lines of code

Vulnerability details

Impact

transfer missing _updateRewards(),Resulting in the loss of from’s reward

Proof of Concept

StaticATokenLM contains the rewards mechanism, when the balance changes, the global _accRewardsPerToken needs to be updated first to calculate the user’s rewardsAccrued more accurately.

Example: mint()/burn() both call _updateRewards() to update _accRewardsPerToken

    function _deposit(
        address depositor,
        address recipient,
        uint256 amount,
        uint16 referralCode,
        bool fromUnderlying
    ) internal returns (uint256) {
        require(recipient != address(0), StaticATokenErrors.INVALID_RECIPIENT);
@>      _updateRewards();

...

        _mint(recipient, amountToMint);

        return amountToMint;
    }


    function _withdraw(
        address owner,
        address recipient,
        uint256 staticAmount,
        uint256 dynamicAmount,
        bool toUnderlying
    ) internal returns (uint256, uint256) {
...
@>      _updateRewards();

...
@>      _burn(owner, amountToBurn);

...
    }        

When transfer()/transerFrom(), the balance is also modified, but without calling _updateRewards() first
The result is that if the user transfers the balance, the difference in rewards accrued by from is transferred to to along with it.
This doesn’t make sense for from.

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256
    ) internal override {
        if (address(INCENTIVES_CONTROLLER) == address(0)) {
            return;
        }
        if (from != address(0)) {
            _updateUser(from);
        }
        if (to != address(0)) {
            _updateUser(to);
        }
    }

Tools Used

Recommended Mitigation Steps

_beforeTokenTransfer first trigger _updateRewards()

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256
    ) internal override {
        if (address(INCENTIVES_CONTROLLER) == address(0)) {
            return;
        }
+       _updateRewards();        
        if (from != address(0)) {
            _updateUser(from);
        }
        if (to != address(0)) {
            _updateUser(to);
        }
    }

Assessed type

Context


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

All reactions

AI Score

7

Confidence

Low