Platform: Code4rena
Start Date: 08/09/2023
Pot Size: $70,000 USDC
Total HM: 8
Participants: 84
Period: 6 days
Judge: gzeon
Total Solo HM: 2
Id: 285
League: ETH
Rank: 20/84
Findings: 2
Award: $683.97
π Selected for report: 0
π Solo Findings: 0
π Selected for report: Bauchibred
Also found by: 0xnev, BARW, Ch_301, J4X, ast3ros, degensec, josephdara
520.8185 USDC - $520.82
Even if a user is no longer on the member list he can still send his tranch tokens to an address that is on the member list and can redeem them through the other address
The member list for a tranch token is a whitelist of addresses that determines which addresses can handle tranch tokens. It is also used to prevent users to redeem tranch tokens by checking if the sender is on the member list when sending a redeem request. The goal here is to freeze the users tranch tokens in case of a malicious activity. The problem arises in the check that is done for a transaction when sending tranch tokens from one account to another. The restricted
modifier on Tranch.transferFrom()
calls detectTransferRestriction(from, to, value)
:
function detectTransferRestriction(address from, address to, uint256 value) public view returns (uint8) { if (!hasMember(to)) { return DESTINATION_NOT_A_MEMBER_RESTRICTION_CODE; } return SUCCESS_CODE; }
This function only check if the to address
is on the member list, not if the from address
is there. This enables an address that is not a member to send its tranch tokens to an member of the list and thereby bypass the restrictions for redemption of tranch tokens.
Example:
Alice steals a huge amount of tranch tokens from different users. This is detected and centrifuge removes the address of Alice from the member list to prevent her from redeeming the stolen tranch tokens. Bob is still on the member list. Shortly before the epoch of the RWA pool on centrifuge ends Alice transfers her stolen tranch tokens to Bob. He sends a redeem request to centrifuge that goes through since he is on the member list. The request is executed shortly after when the epoch of the RWA pool ends, and Bob can redeem the stable coins for the tranch tokens that should have been locked in Aliceβs account.
Manual review
Add a check to detectTransferRestriction
that makes sure that the from address is also a member of the list. If any of the from or to addresses is not on the list, the function should return false and a transfer should not be possible.
Token-Transfer
#0 - c4-pre-sort
2023-09-15T15:46:17Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-09-15T15:46:32Z
raymondfam marked the issue as duplicate of #17
#2 - c4-pre-sort
2023-09-17T05:25:20Z
raymondfam marked the issue as not a duplicate
#3 - c4-pre-sort
2023-09-17T05:25:28Z
raymondfam marked the issue as duplicate of #17
#4 - c4-pre-sort
2023-09-17T05:25:36Z
raymondfam marked the issue as not a duplicate
#5 - c4-pre-sort
2023-09-17T05:25:45Z
raymondfam marked the issue as duplicate of #14
#6 - c4-pre-sort
2023-09-17T05:25:50Z
raymondfam marked the issue as low quality report
#7 - c4-judge
2023-09-26T16:10:22Z
gzeon-c4 marked the issue as duplicate of #779
#8 - c4-judge
2023-09-26T16:11:19Z
gzeon-c4 changed the severity to 2 (Med Risk)
#9 - c4-judge
2023-09-26T16:11:59Z
gzeon-c4 marked the issue as satisfactory
π Selected for report: castle_chain
Also found by: 0xAadi, 0xHelium, 0xLook, 0xblackskull, 0xfuje, 0xmystery, 0xnev, 0xpiken, 7ashraf, BARW, Bauchibred, Bughunter101, Ch_301, JP_Courses, Kaysoft, Krace, MohammedRizwan, SanketKogekar, Sathish9098, alexzoid, ast3ros, btk, catellatech, degensec, fatherOfBlocks, grearlake, imtybik, jkoppel, jolah1, klau5, lsaudit, m_Rassska, merlin, mrudenko, nobody2018, rokinot, rvierdiiev, sandy
163.1547 USDC - $163.15
Root.sol
if the initially set delay is smaller than the MAX_DELAY
Link to code: https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/Root.sol#L34-L40
There is no check in the constructor of Root.sol
that makes sure that the initially set delay is smaller than the MAX_DELAY
. This can lead to delays in the launch of the project in case the dalay is set to more than the MAX_DELAY
since only wards of root can change this value and it would take more than MAX_DELAY
to set a new ward for the root contract. Consider adding a check that ensures that the initially set delay is smaller than MAX_DELAY
deployLiquidityPool
.If the pool doesn't exist, the function will revert at its beginning. Here's the relevant code:
function deployLiquidityPool(uint64 poolId, bytes16 trancheId, address currency) public returns (address) { // @info check if the tranch exist Tranche storage tranche = pools[poolId].tranches[trancheId]; require(tranche.token != address(0), "PoolManager/tranche-does-not-exist"); // Tranche must have been added // @info check is currency is added require(isAllowedAsPoolCurrency(poolId, currency), "PoolManager/currency-not-supported"); // Currency must be supported by pool // @info check if liquidityPool is deployed, so this function can't be called twice with same parameters address liquidityPool = tranche.liquidityPools[currency]; require(liquidityPool == address(0), "PoolManager/liquidityPool-already-deployed"); // @audit redundant check, this line will never be executed require(pools[poolId].createdAt != 0, "PoolManager/pool-does-not-exist");
Unexpected results may occur if the string length is greater than or equal to 32 or 128, respectively.
function testMsgForwarding() public { string memory test = "thisisatet"; bytes32 result1 = _stringToBytes32(test); emit log_bytes32(result1); string memory string1 = _bytes32ToString(result1); console.log("test: %s string1 : %s ", string1); string memory stringWithLeng40 = "1234567890123456789012345678901234567890"; bytes32 result2 = _stringToBytes32(stringWithLeng40); string memory string2 = _bytes32ToString(result2); console.log("stringWithLeng40 : %s result : %s", stringWithLeng40, string2); emit log_bytes32(result2); }
#0 - c4-pre-sort
2023-09-15T16:27:44Z
raymondfam marked the issue as low quality report
#1 - c4-pre-sort
2023-09-15T16:29:22Z
raymondfam marked the issue as remove high or low quality report
#2 - c4-pre-sort
2023-09-17T01:18:37Z
raymondfam marked the issue as sufficient quality report
#3 - c4-judge
2023-09-26T17:47:49Z
gzeon-c4 marked the issue as grade-b
#4 - c4-judge
2023-09-28T10:06:49Z
gzeon-c4 marked the issue as grade-a