Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SavingsAccount.sol Wrong amount in Transfer events #130

Open
code423n4 opened this issue Dec 15, 2021 · 2 comments
Open

SavingsAccount.sol Wrong amount in Transfer events #130

code423n4 opened this issue Dec 15, 2021 · 2 comments
Labels
0 (Non-critical) Code style, clarity, syntax, versioning, off-chain monitoring (events etc), exclude gas optimisation bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments)

Comments

@code423n4
Copy link
Contributor

Handle

WatchPug

Vulnerability details

For the Transfer event, amount is expected to be the amount of tokens transferred, usually equal to the allowance decreased.

However, in the transfer() function, at L402: _amount is transformed into shares.

https://github.com/code-423n4/2021-12-sublime/blob/9df1b7c4247f8631647c7627a8da9bdc16db8b11/contracts/SavingsAccount/SavingsAccount.sol#L393-L416

function transfer(
    uint256 _amount,
    address _token,
    address _strategy,
    address _to
) external override returns (uint256) {
    require(_amount != 0, 'SavingsAccount::transfer zero amount');

    if (_strategy != address(0)) {
        _amount = IYield(_strategy).getSharesForTokens(_amount, _token);
    }

    balanceInShares[msg.sender][_token][_strategy] = balanceInShares[msg.sender][_token][_strategy].sub(
        _amount,
        'SavingsAccount::transfer insufficient funds'
    );

    //update receiver's balance
    balanceInShares[_to][_token][_strategy] = balanceInShares[_to][_token][_strategy].add(_amount);

    emit Transfer(_token, _strategy, msg.sender, _to, _amount);

    return _amount;
}

In the transferFrom() function, at L441: _amount is transformed into shares.

https://github.com/code-423n4/2021-12-sublime/blob/9df1b7c4247f8631647c7627a8da9bdc16db8b11/contracts/SavingsAccount/SavingsAccount.sol#L426-L456

function transferFrom(
    uint256 _amount,
    address _token,
    address _strategy,
    address _from,
    address _to
) external override returns (uint256) {
    require(_amount != 0, 'SavingsAccount::transferFrom zero amount');
    //update allowance
    allowance[_from][_token][msg.sender] = allowance[_from][_token][msg.sender].sub(
        _amount,
        'SavingsAccount::transferFrom allowance limit exceeding'
    );

    if (_strategy != address(0)) {
        _amount = IYield(_strategy).getSharesForTokens(_amount, _token);
    }

    //reduce sender's balance
    balanceInShares[_from][_token][_strategy] = balanceInShares[_from][_token][_strategy].sub(
        _amount,
        'SavingsAccount::transferFrom insufficient allowance'
    );

    //update receiver's balance
    balanceInShares[_to][_token][_strategy] = (balanceInShares[_to][_token][_strategy]).add(_amount);

    emit Transfer(_token, _strategy, _from, _to, _amount);

    return _amount;
}

As a result, the amount in Transfer events is wrong.

PoC

Given:

  • the price per share of yearn USDC vault is 1.2
  1. Alice deposited 12,000 USDC to yearn strategy, received 10,000 share tokens;
  2. Alice transfer() 12,000 USDC to Bob;
  • Expected Result: the amount in the Transfer event is: 12,000;
  • Actual Result: the amount in the Transfer event is: 10,000.
@code423n4 code423n4 added 1 (Low Risk) Assets are not at risk. State handling, function incorrect as to spec, issues with comments bug Something isn't working labels Dec 15, 2021
code423n4 added a commit that referenced this issue Dec 15, 2021
@ritik99 ritik99 added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Jan 8, 2022
@ritik99
Copy link
Collaborator

ritik99 commented Jan 8, 2022

Since the function internally deals with shares rather than the underlying tokens the implementation is actually correct. We'll make it more explicit in the event definition. Since the issue deals with off-chain monitoring we suggest a rating of (0) Non-critical

@0xean
Copy link
Collaborator

0xean commented Jan 21, 2022

0 — Non-critical: Code style, clarity, syntax, versioning, off-chain monitoring (events etc), exclude gas-optimisations.

@0xean 0xean added 0 (Non-critical) Code style, clarity, syntax, versioning, off-chain monitoring (events etc), exclude gas optimisation and removed 1 (Low Risk) Assets are not at risk. State handling, function incorrect as to spec, issues with comments labels Jan 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0 (Non-critical) Code style, clarity, syntax, versioning, off-chain monitoring (events etc), exclude gas optimisation bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments)
Projects
None yet
Development

No branches or pull requests

3 participants