Tigris Trade contest - minhtrng's results

A multi-chain decentralized leveraged exchange featuring instant settlement and guaranteed price execution on 30+ pairs.

General Information

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

Tigris Trade

Findings Distribution

Researcher Performance

Rank: 39/84

Findings: 1

Award: $261.60

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: minhtrng

Also found by: 0Kage, Aymen0909, HollaDieWaldfee, Jeiwan, KingNFT, bin2chen, hansfriese, rvierdiiev

Labels

bug
3 (High Risk)
primary issue
selected for report
sponsor confirmed
upgraded by judge
H-11

Awards

261.5994 USDC - $261.60

External Links

Lines of code

https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/Trading.sol#L275-L282

Vulnerability details

Impact

When adding to a position, the amount of margin pulled from the user is not as much as it should be, which leaks value from the protocol and lowering the collateralization ratio of tigAsset.

Proof of Concept

In Trading.addToPosition the _handleDeposit function is called like this:

_handleDeposit(
    _trade.tigAsset,
    _marginAsset,
    _addMargin - _fee,
    _stableVault,
    _permitData,
    _trader
);

The third parameter with the value of _addMargin - _fee is the amount pulled (or burned in the case of using tigAsset) from the user. The _fee value is calculated as part of the position size like this:

uint _fee = _handleOpenFees(_trade.asset, _addMargin*_trade.leverage/1e18, _trader, _trade.tigAsset, false);

The _handleOpenFees function mints _tigAsset to the referrer, to the msg.sender (if called by a function meant to be executed by bots) and to the protocol itself. Those minted tokens are supposed to be part of the _addMargin value paid by the user. Hence using _addMargin - _fee as the third parameter to _handleDeposit is going to pull or burn less margin than what was accounted for.

An example for correct usage can be seen in initiateMarketOrder:

uint256 _marginAfterFees = _tradeInfo.margin - _handleOpenFees(_tradeInfo.asset, _tradeInfo.margin*_tradeInfo.leverage/1e18, _trader, _tigAsset, false);
uint256 _positionSize = _marginAfterFees * _tradeInfo.leverage / 1e18;
_handleDeposit(_tigAsset, _tradeInfo.marginAsset, _tradeInfo.margin, _tradeInfo.stableVault, _permitData, _trader);

Here the third parameter to _handleDeposit is not _marginAfterFees but _tradeInfo.margin which is what the user has input and is supposed to pay.

Tools Used

Manual Review

In Trading.addToPosition call the _handleDeposit function without subtracting the _fee value:

_handleDeposit(
    _trade.tigAsset,
    _marginAsset,
    _addMargin,
    _stableVault,
    _permitData,
    _trader
);

#0 - GalloDaSballo

2022-12-20T16:16:06Z

Primary because of clean code snippets

#1 - c4-judge

2022-12-20T16:16:09Z

GalloDaSballo marked the issue as primary issue

#2 - c4-sponsor

2023-01-07T11:18:50Z

TriHaz marked the issue as sponsor confirmed

#3 - GalloDaSballo

2023-01-18T13:58:20Z

The Warden has shown how, due to an incorrect computation, less margin is used when adding to a position

While the loss of fees can be considered Medium Severity, I believe that the lack of checks is ultimately allowing for more leverage than intended which not only breaks invariants but can cause further issues (sponsor cited Fees as a defense mechanism against abuse)

For this reason, I believe the finding to be of High Severity.

#4 - c4-judge

2023-01-18T13:58:27Z

GalloDaSballo changed the severity to 3 (High Risk)

#5 - c4-judge

2023-01-22T17:39:01Z

GalloDaSballo marked the issue as selected for report

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