Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding UniswapV2 properties #38

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
initial router setup
tuturu-tech committed Jul 7, 2023
commit 3ad568924574d577b5a282f00244496097bf47cf
23 changes: 23 additions & 0 deletions contracts/AMM/UniswapV2/Setup.sol
Original file line number Diff line number Diff line change
@@ -3,7 +3,9 @@ pragma solidity ^0.6.0;
import "./uni-v2/UniswapV2ERC20.sol";
import "./uni-v2/UniswapV2Pair.sol";
import "./uni-v2/UniswapV2Factory.sol";
import "./uni-v2/UniswapV2Router01.sol";
import "./libraries/UniswapV2Library.sol";
import "./libraries/WETH.sol";

contract Users {
function proxy(
@@ -19,16 +21,21 @@ contract Setup {
UniswapV2Pair pair;
UniswapV2ERC20 testToken1;
UniswapV2ERC20 testToken2;
UniswapV2Router01 router;
WETH9 weth;
Users user;
bool completed;

constructor() public {
weth = new WETH9();
testToken1 = new UniswapV2ERC20();
testToken2 = new UniswapV2ERC20();
factory = new UniswapV2Factory(address(this));
pair = UniswapV2Pair(
factory.createPair(address(testToken1), address(testToken2))
);
router = new UniswapV2Router01(address(factory), address(weth));

// Sort the test tokens we just created, for clarity when writing invariant tests later
(address testTokenA, address testTokenB) = UniswapV2Library.sortTokens(
address(testToken1),
@@ -53,6 +60,22 @@ contract Setup {
uint(-1)
)
);
user.proxy(
address(testToken1),
abi.encodeWithSelector(
testToken1.approve.selector,
address(router),
uint(-1)
)
);
user.proxy(
address(testToken2),
abi.encodeWithSelector(
testToken2.approve.selector,
address(router),
uint(-1)
)
);
}

function _init(uint amount1, uint amount2) internal {
1 change: 0 additions & 1 deletion contracts/AMM/UniswapV2/UniswapV2PropertyTests.sol
Original file line number Diff line number Diff line change
@@ -145,7 +145,6 @@ contract CryticUniswapV2PropertyTests is Setup {
uint256 amount1
) public {
// State before
uint lpTokenBalanceBefore = pair.balanceOf(address(user));
(uint reserve0Before, uint reserve1Before, ) = pair.getReserves();
uint kBefore = reserve0Before * reserve1Before;
bool success;
32 changes: 28 additions & 4 deletions contracts/AMM/UniswapV2/UniswapV2RouterPropertyTests.sol
Original file line number Diff line number Diff line change
@@ -11,12 +11,25 @@ contract CryticUniswapV2RouterPropertyTests is Setup {
event ReservesBefore(uint reserve0, uint reserve1);
event ReservesAfter(uint reserve0, uint reserve1);
event KValues(uint256 a, uint256 b);
event AssertionFailed(uint256 a, uint256 b, string reason);

function _provideLiquidity(
uint256 amount0,
uint256 amount1
uint256 amount1,
uint256 amount0Min,
uint256 amount1Min
) internal returns (uint256, uint256, bool) {
amount0 = _between(amount0, 1000, uint(-1));
amount1 = _between(amount1, 1000, uint(-1));
amount0Min = _between(amount0Min, 0, amount0);
amount1Min = _between(amount1Min, 0, amount1);
uint256 deadline = block.timestamp + 1000;

if (!completed) {
_init(amount0, amount1);
}

router.addLiquidity(address(testToken1), address(testToken2), amount0, amount1, amount0Min, amount1Min, address(user), deadline);
}

function _burnLiquidity(
@@ -34,16 +47,27 @@ contract CryticUniswapV2RouterPropertyTests is Setup {

function test_UniV2_provideLiquidity_IncreasesK(
uint256 amount0,
uint256 amount1
uint256 amount1,
uint256 amount0Min,
uint256 amount1Min
) public {

(uint reserve0Before, uint reserve1Before, ) = pair.getReserves();
uint kBefore = reserve0Before * reserve1Before;

_provideLiquidity(amount0, amount1, amount0Min, amount1Min);

(uint reserve0After, uint reserve1After, ) = pair.getReserves();
uint kAfter = reserve0After * reserve1After;
if (kBefore >= kAfter) {
emit AssertionFailed(kBefore, kAfter, "kBefore is >= kAfter");
}
}

function test_UniV2_provideLiquidity_IncreasesLPSupply(
uint256 amount0,
uint256 amount1
) public {

emit AssertionFailed(0, 9, "Test");
}

// Fails on unbalanced liquidity? TODO
2 changes: 1 addition & 1 deletion contracts/AMM/UniswapV2/echidna-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
testMode: assertion
corpusDir: corpus
seqLen: 25
testLimit: 10000
testLimit: 100000
44 changes: 44 additions & 0 deletions contracts/AMM/UniswapV2/interfaces/IUniswapV2Router02.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);

function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
760 changes: 760 additions & 0 deletions contracts/AMM/UniswapV2/libraries/WETH.sol

Large diffs are not rendered by default.

446 changes: 446 additions & 0 deletions contracts/AMM/UniswapV2/uni-v2/UniswapV2Router02.sol

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -11,7 +11,8 @@
"lint": "npm run lint-check-format && npm run lint-check-links",
"lint-check-format": "prettier --check .",
"lint-check-links": "find . -name '*.md' -not -path './node_modules/*' -print0 | xargs -0 -n1 markdown-link-check",
"echidna-univ2": "echidna . --contract CryticUniswapV2PropertyTests --config ./contracts/AMM/UniswapV2/echidna-config.yaml"
"echidna-univ2": "echidna . --contract CryticUniswapV2PropertyTests --config ./contracts/AMM/UniswapV2/echidna-config.yaml",
"echidna-univ2-router": "echidna . --contract CryticUniswapV2RouterPropertyTests --config ./contracts/AMM/UniswapV2/echidna-config.yaml"
},
"repository": {
"type": "git",