Taiko - wangxx2026's results

A based rollup -- inspired, secured, and sequenced by Ethereum.

General Information

Platform: Code4rena

Start Date: 04/03/2024

Pot Size: $140,000 USDC

Total HM: 19

Participants: 69

Period: 21 days

Judge: 0xean

Total Solo HM: 4

Id: 343

League: ETH

Taiko

Findings Distribution

Researcher Performance

Rank: 15/69

Findings: 1

Award: $1,503.18

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: lightoasis

Also found by: 0xleadwizard, Tendency, alexfilippov314, ladboy233, wangxx2026

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
edited-by-warden
:robot:_60_group
duplicate-60

Awards

1503.1753 USDC - $1,503.18

External Links

Lines of code

https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/team/TimelockTokenPool.sol#L168-L173 https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/team/TimelockTokenPool.sol#L208-L223 https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/team/TimelockTokenPool.sol#L176-L199

Vulnerability details

Impact

User airdropped tokens may be stolen

Proof of Concept

With the withdraw method, we can see that the signature of this withdrawal has no reuse prevention mechanism added to it https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/team/TimelockTokenPool.sol#L168-L173

    function withdraw(address _to, bytes memory _sig) external {
        if (_to == address(0)) revert INVALID_PARAM();
        bytes32 hash = keccak256(abi.encodePacked("Withdraw unlocked Taiko token to: ", _to));
        address recipient = ECDSA.recover(hash, _sig); // @audit The signature can always be reused
        _withdraw(recipient, _to);
    }

With the _getAmountUnlocked method, we can see that the number of tokens that can be withdrawn is unlocked over time. https://github.com/code-423n4/2024-03-taiko/blob/f58384f44dbf4c6535264a472322322705133b11/packages/protocol/contracts/team/TimelockTokenPool.sol#L239-L243

    function _getAmountUnlocked(Grant memory _grant) private view returns (uint128) {
        return _calcAmount(
            _getAmountOwned(_grant), _grant.unlockStart, _grant.unlockCliff, _grant.unlockPeriod
        ); // @audit Unlocked over time
    }

If the user grants another user the right to withdraw the now unlocked amount of tokens, after the user withdraws. As time goes by, more tokens will be unlocked, and the user who got the signature can continue to withdraw tokens, and there is no way to cancel the signature. Restrictions are grant.costPerToken or the user granting the TimelockTokenPool contract can get the number of costToken. If costPerToken is 0, or the number of approvals is max, the user acquiring the signature can acquire as many as they want. If there is a finite number of approvals, the user signing can also withdraw money early after seeing a new grant from the user

Tools Used

Manual Review

Add nonces to prevent the signature from being reused.

Assessed type

Access Control

#0 - c4-pre-sort

2024-03-28T18:50:39Z

minhquanym marked the issue as duplicate of #60

#1 - c4-judge

2024-04-10T11:21:12Z

0xean marked the issue as satisfactory

#2 - c4-judge

2024-04-10T11:21:26Z

0xean changed the severity to 3 (High Risk)

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