Platform: Code4rena
Start Date: 11/01/2023
Pot Size: $60,500 USDC
Total HM: 6
Participants: 69
Period: 6 days
Judge: Trust
Total Solo HM: 2
Id: 204
League: ETH
Rank: 68/69
Findings: 1
Award: $32.36
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: c3phas
Also found by: 0x1f8b, 0xSmartContract, Aymen0909, Bnke0x0, Diana, IllIllI, RaymondFam, Rolezn, Sathish9098, SleepingBugs, Viktor_Cortess, adriro, arialblack14, chaduke, cryptostellar5, cygaar, descharre, dharma09, eyexploit, halden, pavankv, saneryee, tsvetanovv
32.3616 USDC - $32.36
borrower == liquidator
before getting KYC status to save the gasAbove check is performed before checking the KYC status for both borrower and liquidator. Here KYC status is fetching through an external call to the KYC registry contract which cost high amount of gas and if borrower and liquidator are the same then there is unnecessary wastage of gas.
We might think vice versa, where borrower and liquidator are different, but unauthorize. But again it just perform equal to check, which is much cheaper than the external call in above case.
Recommendation : Make sure above check execute before the https://github.com/code-423n4/2023-01-ondo/blob/f3426e5b6b4561e09460b2e6471eb694efdd6c70/contracts/lending/tokens/cCash/CTokenCash.sol#L997-L998
transferTokens
checking twice for KYC status for the same userTokens which are getting transferred via transfer
function have same spender
and src
, which means in the transferTokens
function it will check the KYC status twice for the same address. Its make an external call to the registry contract to get the KYC status for passed address, and doing it twice waste the gas.
File: contracts/lending/tokens/cCash/CTokenCash.sol
function transferTokens( address spender, address src, address dst, uint tokens ) internal returns (uint) { /* Revert if KYC not valid */ require(_getKYCStatus(spender), "Spender not KYC'd"); require(_getKYCStatus(src), "Source not KYC'd"); ... }
File: contracts/lending/tokens/cCash/CTokenCash.sol
function transfer( address dst, uint256 amount ) external override nonReentrant returns (bool) { return transferTokens(msg.sender, msg.sender, dst, amount) == NO_ERROR; }
Recommendation
consider modifiy transferTokens
function to below
function transferTokens( address spender, address src, address dst, uint tokens ) internal returns (uint) { /* Revert if KYC not valid */ if(spender != src) { require(_getKYCStatus(spender), "Spender not KYC'd"); require(_getKYCStatus(src), "Source not KYC'd"); } require(_getKYCStatus(spender), "Spender not KYC'd"); require(_getKYCStatus(dst), "Destination not KYC'd"); ... }
#0 - c4-judge
2023-01-22T19:16:06Z
trust1995 marked the issue as grade-b