Platform: Code4rena
Start Date: 17/02/2022
Pot Size: $75,000 USDC
Total HM: 7
Participants: 23
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 2
Id: 92
League: ETH
Rank: 9/23
Findings: 2
Award: $2,348.43
π Selected for report: 0
π Solo Findings: 0
https://github.com/code-423n4/2022-02-tribe-turbo/blob/main/src/TurboSafe.sol#L222-L236
There will be an interest surplus accumulating in all the master accounting variables (totalBoosted
, getTotalBoostedForVault
and getTotalBoostedAgainstCollateral
).
As getTotalBoostedForVault
and getTotalBoostedAgainstCollateral
are used in the checks against getBoostCapForVault
and getBoostCapForCollateral
by booster.canSafeBoostVault
function on the all new boosts, this will effectively reduce these caps over time (caps figures will remain the same, but vault figures will have a surplus accumulated, so the max possible difference will shrink over time).
This process will end up blocking all the boosts as vault/collateral values be filled up to their caps with surplus vault interest payments.
In other words, the sequence of boost -> slurp -> less (with amount = everything available) leaves safe's accounting variables unchanged as net effect will be zero, while master's variables mentioned above will be increased by the cumulative interest obtained from the vault.
As such kind of sequences are part of the usual workflow, the surplus interest component will fill the master's totals up to the point when they reach the caps and prohibit any new boosts, i.e. the contract become partly stuck, not allowing new funds in
Master.onSafeLess is called after the amount was reduced to the current debt in TurboSafe.less:
https://github.com/code-423n4/2022-02-tribe-turbo/blob/main/src/TurboSafe.sol#L222-L236
As safe accounts for full amounts in boost/slurp/less, the safe and master accounting will diverge, with safe's one being correct, and master's one bloated by the interest payments that were accounted in slurp before:
https://github.com/code-423n4/2022-02-tribe-turbo/blob/main/src/TurboSafe.sol#L274-L289
Master totals are then used to validate new boosts:
https://github.com/code-423n4/2022-02-tribe-turbo/blob/main/src/TurboMaster.sol#L232-L242
Consider moving master.onSafeLess(asset, vault, feiAmount)
up to the VaultLessened
event emission, so the full feiAmount
be accounted.
Now:
emit VaultLessened(msg.sender, vault, feiAmount); // Withdraw the specified amount of Fei from the Vault. vault.withdraw(feiAmount, address(this), address(this)); ... // Repay Fei debt in the Turbo Fuse Pool, unless we would repay nothing. if (feiAmount != 0) require(feiTurboCToken.repayBorrow(feiAmount) == 0, "REPAY_FAILED"); // Call the Master to allow it to update its accounting. master.onSafeLess(asset, vault, feiAmount);
To be:
emit VaultLessened(msg.sender, vault, feiAmount); // Call the Master to allow it to update its accounting. master.onSafeLess(asset, vault, feiAmount); // Withdraw the specified amount of Fei from the Vault. vault.withdraw(feiAmount, address(this), address(this)); ... // Repay Fei debt in the Turbo Fuse Pool, unless we would repay nothing. if (feiAmount != 0) require(feiTurboCToken.repayBorrow(feiAmount) == 0, "REPAY_FAILED");
#0 - transmissions11
2022-02-24T19:28:25Z
looks like a dupe of #30?
#1 - GalloDaSballo
2022-03-19T16:02:43Z
Duplicate of #55
518.6839 USDC - $518.68
https://github.com/code-423n4/2022-02-tribe-turbo/blob/main/src/TurboSafe.sol#L311-312
Vault shares and collateral cTokens might be accessed with sweep
if a cToken have more than one address.
This will disturb the system accounting. The tokens caller obtained will be at a loss for other safe users who will not be able to receive Fei they own per contract records.
This is a fund loss scenario, but the probability is low as such tokens are rare, so setting severity to medium
TurboSafe.sweep controls for one vault and one cTokens address, allowing for sweeping everything else:
https://github.com/code-423n4/2022-02-tribe-turbo/blob/main/src/TurboSafe.sol#L311-312
Some ERC20 have more than one address they can be operated with:
https://github.com/d-xo/weird-erc20#multiple-token-addresses
As address control is used consider providing the ability to input a list of asset addresses to prohibit operations with
#0 - Joeysantoro
2022-02-25T00:22:30Z
This is an extremely niche edge case. I'm inclined to think multiple address tokens will not be approved for Turbo. Will contest to low and leave as acknowledged unless @transmissions11 has other ideas
#1 - transmissions11
2022-02-25T02:50:40Z
Collateral cTokens having multiple addresses is out of scope because we control the Turbo pool and would never make such a token.
As for Vault shares in theory it could be an issue but once again we can vet Vaults to ensure they're not unsafe like this.
#2 - GalloDaSballo
2022-03-13T17:30:07Z
I believe the finding to have merit and appreciate the warden's submission.
However I have to agree with the sponsor in that there is no reason to deploy a second cToken with the same underlying and if that were to happen remediation would be very quick.
So I'll mark the finding as valid but non-critical as it technically is correct, could happen but ultimately is not a vulnerability
#3 - GalloDaSballo
2022-03-21T22:00:29Z
Will judge as a separate report 3/10
#4 - GalloDaSballo
2022-03-21T22:10:19Z
Crazy how with the TUSD Compound Disclosure this finding takes a different meaning.
With the additional information I have : https://medium.com/chainsecurity/trueusd-compound-vulnerability-bc5b696d29e2
I believe the finding is of Low Severity and will re-rate to 5/10 as a single QA report.
Ultimately I believe this can happen and if that were the case the finding could have a high impact, however the likelihood is extremely low, and would require the sponsor to mistakenly add a token with multiple address.
#5 - CloudEllie
2022-03-25T03:38:24Z
Since this issue was downgraded to a QA level, and the warden did not submit a separate QA report, we've renamed this one to "QA report" for consistency.
The original title, for the record, was "TurboSafe.sweep can't control several addresses per token."