-
Notifications
You must be signed in to change notification settings - Fork 167
/
TBPoolJoinExitPoolNoFee.sol
66 lines (49 loc) · 2.26 KB
/
TBPoolJoinExitPoolNoFee.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import "../../BNum.sol";
pragma solidity 0.5.12;
// This test is similar to TBPoolJoinExit but with no exit fee
contract TBPoolJoinExitNoFee is BNum {
bool public echidna_no_bug_found = true;
// joinPool models the BPool.joinPool behavior for one token
function joinPool(uint poolAmountOut, uint poolTotal, uint _records_t_balance)
internal pure returns(uint)
{
uint ratio = bdiv(poolAmountOut, poolTotal);
require(ratio != 0, "ERR_MATH_APPROX");
uint bal = _records_t_balance;
uint tokenAmountIn = bmul(ratio, bal);
return tokenAmountIn;
}
// exitPool models the BPool.exitPool behavior for one token where no fee is applied
function exitPoolNoFee(uint poolAmountIn, uint poolTotal, uint _records_t_balance)
internal pure returns(uint)
{
uint ratio = bdiv(poolAmountIn, poolTotal);
require(ratio != 0, "ERR_MATH_APPROX");
uint bal = _records_t_balance;
uint tokenAmountOut = bmul(ratio, bal);
return tokenAmountOut;
}
// This function model an attacker calling joinPool - exitPool and taking advantage of potential rounding
// issues to generate free pool token
function joinAndExitNoFeePool(uint poolAmountOut, uint poolAmountIn, uint poolTotal, uint _records_t_balance)
public
{
uint tokenAmountIn = joinPool(poolAmountOut, poolTotal, _records_t_balance);
// We constraint poolTotal and _records_t_balance
// To have "realistic" values
require(poolTotal <= 100 ether);
require(poolTotal >= 1 ether);
require(_records_t_balance <= 10 ether);
require(_records_t_balance >= 10**6);
poolTotal = badd(poolTotal, poolAmountOut);
_records_t_balance = badd(_records_t_balance, tokenAmountIn);
require(tokenAmountIn > 0); // prevent triggering the free token generation from joinPool
require(poolTotal >= poolAmountIn);
uint tokenAmountOut = exitPoolNoFee(poolAmountIn, poolTotal, _records_t_balance);
require(_records_t_balance >= tokenAmountOut);
// We try to generate free pool share
require(poolAmountOut > poolAmountIn);
require(tokenAmountOut == tokenAmountIn);
echidna_no_bug_found = false;
}
}