Platform: Code4rena
Start Date: 09/12/2022
Pot Size: $90,500 USDC
Total HM: 35
Participants: 84
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 12
Id: 192
League: ETH
Rank: 38/84
Findings: 3
Award: $271.34
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xsomeone
Also found by: 0xhacksmithh, 8olidity, Critical, Ruhum, SamGMK, Secureverse, Tointer, __141345__, aviggiano, rotcivegaf
133.3608 USDC - $133.36
https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/StableVault.sol#L44-L51 https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/StableVault.sol#L65-L72
When any of the listed stablecoins depeg, the bad coins will drive out the good coins, leaving only bad coins in StableVault, resulting in the collapse of StableVault.
Given:
StableVault listed three stablecoins: USDD, USDC, and USDT.
Alice could not get any USDC back; she could only choose to withdraw USDD and bear the loss.
Each StableVault should only be allowed to wrap one token
to its corresponding tigAsset
.
#0 - GalloDaSballo
2022-12-18T16:50:20Z
External risk (Med), but no liquidity premium in code leads me to think this is valid
#1 - c4-judge
2022-12-22T14:48:19Z
GalloDaSballo marked the issue as duplicate of #462
#2 - GalloDaSballo
2022-12-22T14:48:21Z
Marking as dup for No Liquidity Premium
#3 - c4-judge
2023-01-22T17:36:59Z
GalloDaSballo marked the issue as satisfactory
124.2162 USDC - $124.22
initiateMarketOrder()
can be called with a signed off-chain price data from the past _validSignatureTimer
and that price
will be taken as the open price of the position.
Because the difference of the current price to the price
from _validSignatureTimer
ago is known to the caller, it will be possible for the user to create a long position at a price 2% lower than the current market price, or a short position at a price 2% higher than the current market price.
If the _validSignatureTimer
is long enough, combining with leverage, the attacker will be able to disrupt the market by draining all the profits from the other regular users.
function verifyPrice( uint256 _validSignatureTimer, uint256 _asset, bool _chainlinkEnabled, address _chainlinkFeed, PriceData calldata _priceData, bytes calldata _signature, mapping(address => bool) storage _isNode ) external view { address _provider = ( keccak256(abi.encode(_priceData)) ).toEthSignedMessageHash().recover(_signature); require(_provider == _priceData.provider, "BadSig"); require(_isNode[_provider], "!Node"); require(_asset == _priceData.asset, "!Asset"); require(!_priceData.isClosed, "Closed"); require(block.timestamp >= _priceData.timestamp, "FutSig"); require(block.timestamp <= _priceData.timestamp + _validSignatureTimer, "ExpSig"); require(_priceData.price > 0, "NoPrice"); if (_chainlinkEnabled && _chainlinkFeed != address(0)) { int256 assetChainlinkPriceInt = IPrice(_chainlinkFeed).latestAnswer(); if (assetChainlinkPriceInt != 0) { uint256 assetChainlinkPrice = uint256(assetChainlinkPriceInt) * 10**(18 - IPrice(_chainlinkFeed).decimals()); require( _priceData.price < assetChainlinkPrice+assetChainlinkPrice*2/100 && _priceData.price > assetChainlinkPrice-assetChainlinkPrice*2/100, "!chainlinkPrice" ); } } }
Signed _priceData
should only be allowed for SL/TP and match limit orders. For those orders, only a priceData with a timestamp after the created timestamp of the order can be used.
#0 - c4-judge
2022-12-22T14:52:01Z
GalloDaSballo marked the issue as duplicate of #108
#1 - c4-judge
2023-01-16T09:45:04Z
GalloDaSballo changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-01-22T17:49:33Z
GalloDaSballo marked the issue as satisfactory
🌟 Selected for report: yjrwkk
Also found by: 0x4non, 0xDecorativePineapple, 0xdeadbeef0x, Avci, Critical, Deivitto, Dinesh11G, Englave, Tointer, ak1, chaduke, izhelyazkov, pwnforce, rbserver, rvierdiiev, unforgiven
13.7578 USDC - $13.76
function deposit(address _token, uint256 _amount) public { require(allowed[_token], "Token not listed"); IERC20(_token).transferFrom(_msgSender(), address(this), _amount); IERC20Mintable(stable).mintFor( _msgSender(), _amount*(10**(18-IERC20Mintable(_token).decimals())) ); }
deposit
will revert at L49 for tokens with decimals
> 18.
Consider checking if the token's decimals
< 18 in listToken()
.
#0 - c4-judge
2022-12-20T15:43:24Z
GalloDaSballo marked the issue as duplicate of #533
#1 - c4-judge
2023-01-22T17:45:08Z
GalloDaSballo marked the issue as satisfactory