// SPDX-License-Identifier: UNLICENCED
pragma solidity ^0.7.5;
interface ERC20 {
function balanceOf(address _owner) external view returns (uint256 balance);
function transfer(address _to, uint256 _value) external returns (bool success);
function approve(address _spender, uint256 _value) external returns (bool success);
}
contract MrSlipper {
receive() external payable {}
function withdrawToken(address token) public {
uint balance = ERC20(token).balanceOf(address(this));
ERC20(token).transfer(msg.sender, balance);
}
function withdrawETH(uint amt) public {
msg.sender.transfer(amt);
}
uint[] public venues;
mapping(uint => address) public venue_selector;
// Trading functions ---------------------
function trade(uint amount_in, address token_in, address token_out, uint venue) public {
address ven = venue_selector[venue];
ven.delegatecall(abi.encodeWithSignature("execute(uint256,address,address)", amount_in, token_in, token_out));
}
function two_leg(uint amount_in, address token_in, address intermediate_token, uint venue1, uint venue2, bool debug) public {
uint start = ERC20(token_in).balanceOf(address(this));
trade(amount_in, token_in, intermediate_token, venue1);
trade(ERC20(intermediate_token).balanceOf(address(this)), intermediate_token, token_in, venue2);
if (!debug){
require(ERC20(token_in).balanceOf(address(this)) > start, "Trade not profitable");
}
}
function three_leg(uint amount_in, address token_in, address intermediate_token1, address intermediate_token2, uint venue1, uint venue2, uint venue3, bool debug) public {
uint start = ERC20(token_in).balanceOf(address(this));
trade(amount_in, token_in, intermediate_token1, venue1);
trade(ERC20(intermediate_token1).balanceOf(address(this)), intermediate_token1, intermediate_token2, venue2);
trade(ERC20(intermediate_token2).balanceOf(address(this)), intermediate_token2, token_in, venue3);
if (!debug){
require(ERC20(token_in).balanceOf(address(this)) > start, "Trade not profitable");
}
}
// Venue functions ---------------------
function addVenueWrapper(uint index, address address_) public {
// Assign each venue a unique index. Indices can be overwritten.
venue_selector[index] = address_;
venues.push(index);
}
function approve(address token_address, address spender, uint amount) public {
ERC20(token_address).approve(spender, amount);
}
}
{
"compilationTarget": {
"browser/Slipper_cutback.sol": "MrSlipper"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"address_","type":"address"}],"name":"addVenueWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token_address","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_in","type":"uint256"},{"internalType":"address","name":"token_in","type":"address"},{"internalType":"address","name":"intermediate_token1","type":"address"},{"internalType":"address","name":"intermediate_token2","type":"address"},{"internalType":"uint256","name":"venue1","type":"uint256"},{"internalType":"uint256","name":"venue2","type":"uint256"},{"internalType":"uint256","name":"venue3","type":"uint256"},{"internalType":"bool","name":"debug","type":"bool"}],"name":"three_leg","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_in","type":"uint256"},{"internalType":"address","name":"token_in","type":"address"},{"internalType":"address","name":"token_out","type":"address"},{"internalType":"uint256","name":"venue","type":"uint256"}],"name":"trade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_in","type":"uint256"},{"internalType":"address","name":"token_in","type":"address"},{"internalType":"address","name":"intermediate_token","type":"address"},{"internalType":"uint256","name":"venue1","type":"uint256"},{"internalType":"uint256","name":"venue2","type":"uint256"},{"internalType":"bool","name":"debug","type":"bool"}],"name":"two_leg","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"venue_selector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"venues","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amt","type":"uint256"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]