Skip to content

Commit

Permalink
impl DEXV2 to support bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
wangjj9219 committed Sep 9, 2024
1 parent 95e0d85 commit 9065b31
Show file tree
Hide file tree
Showing 15 changed files with 925 additions and 100 deletions.
133 changes: 37 additions & 96 deletions contracts/dex/DEX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,116 +10,75 @@ import {IDEX} from "./IDEX.sol";
/// @dev This contracts will interact with dex pallet
contract DEX is IDEX {
/// @dev The DEX precompile address.
address private constant PRECOMPILE =
address(0x0000000000000000000000000000000000000405);
address internal constant PRECOMPILE = address(0x0000000000000000000000000000000000000405);

/// @inheritdoc IDEX
function getLiquidityPool(
address tokenA,
address tokenB
) public view override returns (uint256, uint256) {
function getLiquidityPool(address tokenA, address tokenB) public view override returns (uint256, uint256) {
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) = PRECOMPILE.staticcall(
abi.encodeWithSignature(
"getLiquidityPool(address,address)",
tokenA,
tokenB
)
);
(bool success, bytes memory returnData) =
PRECOMPILE.staticcall(abi.encodeWithSignature("getLiquidityPool(address,address)", tokenA, tokenB));
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (uint256, uint256));
}

/// @inheritdoc IDEX
function getLiquidityTokenAddress(
address tokenA,
address tokenB
) public view override returns (address) {
function getLiquidityTokenAddress(address tokenA, address tokenB) public view override returns (address) {
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) = PRECOMPILE.staticcall(
abi.encodeWithSignature(
"getLiquidityTokenAddress(address,address)",
tokenA,
tokenB
)
);
(bool success, bytes memory returnData) =
PRECOMPILE.staticcall(abi.encodeWithSignature("getLiquidityTokenAddress(address,address)", tokenA, tokenB));
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (address));
}

/// @inheritdoc IDEX
function getSwapTargetAmount(
address[] memory path,
uint256 supplyAmount
) public view override returns (uint256) {
for (uint i = 0; i < path.length; i++) {
function getSwapTargetAmount(address[] memory path, uint256 supplyAmount) public view override returns (uint256) {
for (uint256 i = 0; i < path.length; i++) {
require(path[i] != address(0), "DEX: token is zero address");
}
require(supplyAmount != 0, "DEX: supplyAmount is zero");

(bool success, bytes memory returnData) = PRECOMPILE.staticcall(
abi.encodeWithSignature(
"getSwapTargetAmount(address[],uint256)",
path,
supplyAmount
)
);
(bool success, bytes memory returnData) =
PRECOMPILE.staticcall(abi.encodeWithSignature("getSwapTargetAmount(address[],uint256)", path, supplyAmount));

Check warning on line 51 in contracts/dex/DEX.sol

View workflow job for this annotation

GitHub Actions / build

Line length must be no more than 120 but current length is 121
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (uint256));
}

/// @inheritdoc IDEX
function getSwapSupplyAmount(
address[] memory path,
uint256 targetAmount
) public view override returns (uint256) {
for (uint i = 0; i < path.length; i++) {
function getSwapSupplyAmount(address[] memory path, uint256 targetAmount) public view override returns (uint256) {
for (uint256 i = 0; i < path.length; i++) {
require(path[i] != address(0), "DEX: token is zero address");
}
require(targetAmount != 0, "DEX: targetAmount is zero");

(bool success, bytes memory returnData) = PRECOMPILE.staticcall(
abi.encodeWithSignature(
"getSwapSupplyAmount(address[],uint256)",
path,
targetAmount
)
);
(bool success, bytes memory returnData) =
PRECOMPILE.staticcall(abi.encodeWithSignature("getSwapSupplyAmount(address[],uint256)", path, targetAmount));

Check warning on line 67 in contracts/dex/DEX.sol

View workflow job for this annotation

GitHub Actions / build

Line length must be no more than 120 but current length is 121
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (uint256));
}

/// @inheritdoc IDEX
function swapWithExactSupply(
address[] memory path,
uint256 supplyAmount,
uint256 minTargetAmount
) public override returns (bool) {
for (uint i = 0; i < path.length; i++) {
function swapWithExactSupply(address[] memory path, uint256 supplyAmount, uint256 minTargetAmount)
public
override
returns (bool)
{
for (uint256 i = 0; i < path.length; i++) {
require(path[i] != address(0), "DEX: token is zero address");
}
require(supplyAmount != 0, "DEX: supplyAmount is zero");
Expand All @@ -134,27 +93,20 @@ contract DEX is IDEX {
)
);
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

emit Swaped(
msg.sender,
path,
supplyAmount,
abi.decode(returnData, (uint256))
);
emit Swaped(msg.sender, path, supplyAmount, abi.decode(returnData, (uint256)));
return true;
}

/// @inheritdoc IDEX
function swapWithExactTarget(
address[] memory path,
uint256 targetAmount,
uint256 maxSupplyAmount
) public override returns (bool) {
for (uint i = 0; i < path.length; i++) {
function swapWithExactTarget(address[] memory path, uint256 targetAmount, uint256 maxSupplyAmount)
public
override
returns (bool)
{
for (uint256 i = 0; i < path.length; i++) {
require(path[i] != address(0), "DEX: token is zero address");
}
require(targetAmount != 0, "DEX: targetAmount is zero");
Expand All @@ -169,17 +121,10 @@ contract DEX is IDEX {
)
);
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

emit Swaped(
msg.sender,
path,
abi.decode(returnData, (uint256)),
targetAmount
);
emit Swaped(msg.sender, path, abi.decode(returnData, (uint256)), targetAmount);
return true;
}

Expand Down Expand Up @@ -208,9 +153,7 @@ contract DEX is IDEX {
)
);
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

emit AddedLiquidity(msg.sender, tokenA, tokenB, maxAmountA, maxAmountB);
Expand Down Expand Up @@ -241,9 +184,7 @@ contract DEX is IDEX {
)
);
assembly {
if eq(success, 0) {
revert(add(returnData, 0x20), returndatasize())
}
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

emit RemovedLiquidity(msg.sender, tokenA, tokenB, removeShare);
Expand Down
121 changes: 121 additions & 0 deletions contracts/dex/DEXV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity ^0.8.0;

import {IDEX} from "./IDEX.sol";
import {DEX} from "./DEX.sol";
import {IBootstrap} from "./IBootstrap.sol";

/// @title DEX Predeploy Contract, V2, support bootstrap
/// @author Acala Developers
/// @notice You can use this predeploy contract to call dex pallet
/// @dev This contracts will interact with dex pallet
contract DEXV2 is DEX, IBootstrap {
/// @inheritdoc IBootstrap
function getProvisionPool(address tokenA, address tokenB) public view override returns (uint256, uint256) {
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) =
PRECOMPILE.staticcall(abi.encodeWithSignature("getProvisionPool(address,address)", tokenA, tokenB));
assembly {
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (uint256, uint256));
}

/// @inheritdoc IBootstrap
function getProvisionPoolOf(address who, address tokenA, address tokenB)
public
view
override
returns (uint256, uint256)
{
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) = PRECOMPILE.staticcall(
abi.encodeWithSignature("getProvisionPoolOf(address, address,address)", who, tokenA, tokenB)
);
assembly {
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (uint256, uint256));
}

/// @inheritdoc IBootstrap
function getInitialShareExchangeRate(address tokenA, address tokenB)
public
view
override
returns (uint256, uint256)
{
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) = PRECOMPILE.staticcall(
abi.encodeWithSignature("getInitialShareExchangeRate(address,address)", tokenA, tokenB)
);
assembly {
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return abi.decode(returnData, (uint256, uint256));
}

/// @inheritdoc IBootstrap
function addProvision(address tokenA, address tokenB, uint256 amountA, uint256 amountB)
public
override
returns (bool)
{
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");
require(amountA != 0 || amountB != 0, "DEX: invalid contribution amount");

(bool success, bytes memory returnData) = PRECOMPILE.call(
abi.encodeWithSignature(
"addProvision(address,address,address,uint256,uint256)", msg.sender, tokenA, tokenB, amountA, amountB
)
);
assembly {
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

emit AddProvision(msg.sender, tokenA, tokenB, amountA, amountB);
return true;
}

/// @inheritdoc IBootstrap
function claimDexShare(address who, address tokenA, address tokenB) public override returns (bool) {
require(who != address(0), "DEX: who is zero address");
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) =
PRECOMPILE.call(abi.encodeWithSignature("claimDexShare(address,address,address)", who, tokenA, tokenB));
assembly {
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

emit ClaimShare(who, tokenA, tokenB, abi.decode(returnData, (uint256)));
return true;
}

/// @inheritdoc IBootstrap
function refundProvision(address who, address tokenA, address tokenB) public override returns (bool) {
require(who != address(0), "DEX: who is zero address");
require(tokenA != address(0), "DEX: tokenA is zero address");
require(tokenB != address(0), "DEX: tokenB is zero address");

(bool success, bytes memory returnData) =
PRECOMPILE.call(abi.encodeWithSignature("refundProvision(address,address,address)", who, tokenA, tokenB));
assembly {
if eq(success, 0) { revert(add(returnData, 0x20), returndatasize()) }
}

return true;
}
}
Loading

0 comments on commit 9065b31

Please sign in to comment.