Skip to content

Commit

Permalink
0xCallee to v4 (#383)
Browse files Browse the repository at this point in the history
* add WETH interface; fix typo

* pay protocol fee in ETH

* update contracts to 0x v4 order format and methods

* 0xcallee passes unit tests

* update mock exchange

* update ropsten 0xcallee script

* fix network id

* remove _directlyTrade

* lint ropsten test file

* Update 0x packages

* Rename Trade0x to TradeCallee. Fix weth reverted on fallback

* Use new callee address in tests

* remove old e2e test

* Update callee to accpet eth

* Fix Calle test and remove e2e test from circle ci

* cleanup

Co-authored-by: Anton Cheng <[email protected]>
  • Loading branch information
alexisgauba and antoncoding authored Apr 19, 2021
1 parent d7dda32 commit 79cd1c4
Show file tree
Hide file tree
Showing 16 changed files with 16,121 additions and 4,506 deletions.
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ workflows:
- integration-test:
requires:
- build
- e2e-test:
context: COVERALLS_REPO_TOKEN
requires:
- build
# - e2e-test:
# context: COVERALLS_REPO_TOKEN
# requires:
# - build
- coverage:
context: COVERALLS_REPO_TOKEN
requires:
Expand Down
2 changes: 1 addition & 1 deletion .solcover.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ module.exports = {
'mocks/',
'packages/',
'external/canonical-weth',
'external/callees/Trade0x.sol'
'external/callees/TradeCallee.sol'
]
}
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ To deploy a new `PermitCallee.sol`, it is recommended to use the `deployPermitCa
truffle exec scripts/deployPermitCallee.js --network kovan --gasPrice 50000000000
```

### Trade0x Callee Deployment
the `Trade0x.sol` contract allow to batch 0x trading transactions with Gamma operate actions through the Call action.
To deploy a new `Trade0x.sol`, it is recommended to use the `deployTrade0x` truffle script inside the `scripts` folder.
### TradeCallee Deployment
the `TradeCallee.sol` contract allow to batch 0x trading transactions with Gamma operate actions through the Call action.
To deploy a new `TradeCallee.sol`, it is recommended to use the `deployTrade0x` truffle script inside the `scripts` folder.

**Input**
```sh
truffle exec scripts/deployTrade0x.js --network kovan --exchange 0xf1ec7d0ba42f15fb5c9e3adbe86431973e44764c --assetproxy 0xaa460127562482faa5df42f2c39a025cd4a1cc0a --staking 0xe94cb304b3f515be7c95fedcfa249a84995fd748 --weth 0xd0A1E359811322d97991E03f863a0C30C2cF029C --controller 0xdEE7D0f8CcC0f7AC7e45Af454e5e7ec1552E8e4e --gasPrice 50000000000
truffle exec scripts/deployTrade0x.js --network ropsten --exchange 0xdef1c0ded9bec7f1a1670819833240f027b25eff --weth 0xc778417e063141139fce010982780140aa0cd5ab --controller 0x7e9beaccdccee88558aaa2dc121e52ec6226864e --gas 100000000000
```

## Linting
Expand Down
168 changes: 0 additions & 168 deletions contracts/external/callees/Trade0x.sol

This file was deleted.

112 changes: 112 additions & 0 deletions contracts/external/callees/TradeCallee.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* SPDX-License-Identifier: UNLICENSED
*/

pragma solidity 0.6.10;

pragma experimental ABIEncoderV2;

import {CalleeInterface} from "../../interfaces/CalleeInterface.sol";
import {ZeroXExchangeInterface} from "../../interfaces/ZeroXExchangeInterface.sol";
import {ERC20Interface} from "../../interfaces/ERC20Interface.sol";
import {WETH9Interface} from "../../interfaces/WETH9Interface.sol";

import {SafeERC20} from "../../packages/oz/SafeERC20.sol";

/**
* @author Opyn Team
* @title TradeCallee
* @notice callee contract to trade on 0x.
*/
contract TradeCallee is CalleeInterface {
using SafeERC20 for ERC20Interface;

///@dev 0x protocol fee to fill 1 order
uint256 private PROTOCOL_FEE_BASE = 70000;

ZeroXExchangeInterface public exchange;
WETH9Interface public weth;

address public controller;

constructor(
address _exchange,
address _weth,
address _controller
) public {
exchange = ZeroXExchangeInterface(_exchange);
weth = WETH9Interface(_weth);
controller = _controller;
}

/**
* @notice fill 0x order
* @param _sender the original sender who wants to trade on 0x
* @param _data abi-encoded order, fillamount, signature and _sender. fee payer is the address we pull weth from.
*/
function callFunction(address payable _sender, bytes memory _data) external override {
require(msg.sender == controller, "TradeCallee: sender is not controller");

(
address trader,
ZeroXExchangeInterface.LimitOrder[] memory orders,
ZeroXExchangeInterface.Signature[] memory signatures,
uint128[] memory takerTokenFillAmounts,
bool revertIfIncomplete
) = abi.decode(
_data,
(address, ZeroXExchangeInterface.LimitOrder[], ZeroXExchangeInterface.Signature[], uint128[], bool)
);

// _sender is not always the user, could be the payable proxy, so we use tx.origin.
// won't work with Argent (Wallet Connect).
require(
tx.origin == trader,
"TradeCallee: funds can only be transferred in from the person sending the transaction"
);

for (uint256 i = 0; i < orders.length; i++) {
address takerAsset = orders[i].takerToken;
// transfer takerAsset from trader to this contract
ERC20Interface(takerAsset).safeTransferFrom(trader, address(this), takerTokenFillAmounts[i]);
// approve the 0x ERC20 Proxy to transfer takerAsset from this contract
ERC20Interface(takerAsset).safeIncreaseAllowance(address(exchange), takerTokenFillAmounts[i]);
}

// pull weth (to pay 0x) from _sender address
uint256 protocolFee = tx.gasprice * PROTOCOL_FEE_BASE * orders.length;
weth.transferFrom(_sender, address(this), protocolFee);
weth.withdraw(protocolFee); //withdraw ETH from WETH to pay protocol fee

// send txn paying protocol fee in ETH
exchange.batchFillLimitOrders{value: protocolFee}(
orders,
signatures,
takerTokenFillAmounts,
revertIfIncomplete
);

for (uint256 i = 0; i < orders.length; i++) {
// address asset = decodeERC20Asset(order[i].makerAssetData);
address asset = orders[i].makerToken;
// transfer swapped token to sender
uint256 balance = ERC20Interface(asset).balanceOf(address(this));
if (balance > 0) {
ERC20Interface(asset).safeTransfer(trader, balance);
}

// asset = decodeERC20Asset(order[i].takerAssetData);
asset = orders[i].takerToken;
// transfer the taker asset back to the user if the order wasn't fully filled
balance = ERC20Interface(asset).balanceOf(address(this));
if (balance > 0) {
ERC20Interface(asset).safeTransfer(trader, balance);
}
}
}

/**
* @notice fallback function which allow ETH to be sent to this contract
*/
fallback() external payable {}
}
Loading

0 comments on commit 79cd1c4

Please sign in to comment.