Timeswap contest - codeislight's results

Like Uniswap, but for lending & borrowing.

General Information

Platform: Code4rena

Start Date: 20/01/2023

Pot Size: $90,500 USDC

Total HM: 10

Participants: 59

Period: 7 days

Judge: Picodes

Total Solo HM: 4

Id: 206

League: ETH

Timeswap

Findings Distribution

Researcher Performance

Rank: 6/59

Findings: 1

Award: $4,626.00

🌟 Selected for report: 1

🚀 Solo Findings: 1

Findings Information

🌟 Selected for report: codeislight

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
selected for report
sponsor confirmed
M-05

Awards

4626.0034 USDC - $4,626.00

External Links

Lines of code

https://github.com/code-423n4/2023-01-timeswap/blob/ef4c84fb8535aad8abd6b67cc45d994337ec4514/packages/v2-library/src/FullMath.sol#L62

Vulnerability details

Impact

The vulnerability originate from insufficient checking in add512 function, where the AddOverflow revert gets bypassed, essentially the function assumes that an overflow only happen if (addendA1 > sum1), where in the case that it's possible for it overflow in the case that addendA1 == sum1, which can be resulted through assigning a value that makes ( lt(sum0, addendA0) == 1 ) <=> sum0 < addendA0, which can only be achieved normally by overflowing the least significant addition. then we can simply break the overflow check by assigning an overflowing values which results in add(addendA1, addendB1) > type(256).max && addendA1 <= sum1, then we will manage to bypass the revert check and overflow the most significant part of add512 values.

the previous attack vector can lead to a manipulation in leverage and deleverage functions, in a way that it would result in more tokens for the user

Proof of Concept

inputing the following values result in an overflow: uint256 addendA0 = 1 uint256 addendA1 = 100 uint256 addendB0 = 115792089237316195423570985008687907853269984665640564039457584007913129639935 (uint256 max value) uint256 addendB1 = 115792089237316195423570985008687907853269984665640564039457584007913129639935 (uint256 max value)

results in: sum0 = 0 sum1 = 100

the expected behavior is to revert since, A1 + B1 result in a value that overflows, but instead consider it as a valid behavior due to the insufficient checking.

Abstraction: A1 - A0 + B1 - B0 = S1 - S0

S0 = A0 + B0 S1 = A1 + B1 + ( if S0 overflows [+ 1]) ensure A1 <= S1 revert only on A1 > S1

in the case of S0 overflows: S1 = A1 + B1 + 1

require(A1 <= S1) is not most suited check, due to the fact that in the case of A1 == S1 check, it can still overflows if S1 = A1 + B1 + 1 overflows. which would bypass A1 > S1 revert check.

the major impact affects the leverage() and deleverage() result in values which are not expected.

Tools Used

add a an equality check for if statement in add512 function.

function add512(uint256 addendA0, uint256 addendA1, uint256 addendB0, uint256 addendB1) public pure returns (uint256 sum0, uint256 sum1) { assembly { sum0 := add(addendA0, addendB0) carry := lt(sum0, addendA0) sum1 := add(add(addendA1, addendB1), carry) } if (addendA1 > sum1 || ((sum1 == addendA1 || sum1 == addendB1) && (carry < addendA0 || carry < addendB0)) ) revert AddOverflow(addendA0, addendA1, addendB0, addendB1); // }

#0 - Picodes

2023-02-03T08:29:30Z

No explanation related to how this could lead to errors in leverage or deleverage.

#1 - c4-judge

2023-02-03T08:29:40Z

Picodes changed the severity to 2 (Med Risk)

#2 - c4-sponsor

2023-02-08T14:21:13Z

vhawk19 marked the issue as sponsor confirmed

#3 - vhawk19

2023-02-08T14:22:04Z

Fixed in PR

#4 - c4-judge

2023-02-12T22:28:47Z

Picodes marked the issue as satisfactory

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