Skip to content

Latest commit

 

History

History
71 lines (56 loc) · 3.04 KB

075.md

File metadata and controls

71 lines (56 loc) · 3.04 KB

Powerful Honeysuckle Anteater

High

Abond token transferFrom has a flaw which leads to an unwanted state

Summary

TransferFrom function in the ABONDToken contract sets the updated fromState, wrongly to the msg.sender, instead of the from address, which gave approval to the msg.sender.

Root Cause

transferFrom's purpose is to give other users approvals for transfers, so it should update the state of the from user specified. The problem is that we are updating userStates[msg.sender] for msg.sender instead of userStates[from] Reference; Abond_Token.sol#L147-L170

    function transferFrom(address from, address to, uint256 value) public override returns (bool) {
        // check the input params are non zero
        require(from != address(0) && to != address(0), "Invalid User");

        // get the sender and receiver state
        State memory fromState = userStates[from];
        State memory toState = userStates[to];

        // update receiver state
        toState = Colors._credit(fromState, toState, uint128(value));
        userStates[to] = toState;

        // update sender state
        fromState = Colors._debit(fromState, uint128(value));
        //@audit-issue this is using msg.sender instead of "from" address
@>>     userStates[msg.sender] = fromState;

        // transfer abond
        super.transferFrom(from, to, value);
        return true;
    }

Attack Path

  1. User A gives approval to User B to transfer ABOND tokens.
  2. User B transfers the token using transferFrom.
  3. The state becomes corrupted as User B receives the updated state of User A.

Another possible scenario is yield duplication.
A malicious party could exploit this by using two separate addresses, one of which has a better fromState in terms of ethBacked, and duplicate that state to another address using transferFrom.

Impact

The user state logic in the ABOND token is utilized in the Treasury and Borrow contracts to calculate yield. This could potentially increase or decrease rewards. A malicious party could exploit this to print free yield by duplicating a better state.

Mitigation

    function transferFrom(address from, address to, uint256 value) public override returns (bool) {
        // check the input params are non zero
        require(from != address(0) && to != address(0), "Invalid User");

        // get the sender and receiver state
        State memory fromState = userStates[from];
        State memory toState = userStates[to];

        // update receiver state
        toState = Colors._credit(fromState, toState, uint128(value));
        userStates[to] = toState;

        // update sender state
        fromState = Colors._debit(fromState, uint128(value));
-       userStates[msg.sender] = fromState;
+       userStates[from] = fromState;

        // transfer abond
        super.transferFrom(from, to, value);
        return true;
    }