pragma solidity ^0.4.19;
import { Exchange } from "../../protocol/Exchange/Exchange.sol";
import { EtherDelta } from "../EtherDelta/EtherDelta.sol";
import { Ownable } from "../../utils/Ownable/Ownable.sol";
import { Token } from "../../tokens/Token/Token.sol";
contract Arbitrage is Ownable {
Exchange exchange;
EtherDelta etherDelta;
address proxyAddress;
uint256 constant MAX_UINT = 2**256 - 1;
function Arbitrage(address _exchangeAddress, address _etherDeltaAddress, address _proxyAddress) {
exchange = Exchange(_exchangeAddress);
etherDelta = EtherDelta(_etherDeltaAddress);
proxyAddress = _proxyAddress;
}
function setAllowances(address tokenAddress) external onlyOwner {
Token token = Token(tokenAddress);
token.approve(address(etherDelta), MAX_UINT);
token.approve(proxyAddress, MAX_UINT);
token.approve(owner, MAX_UINT);
}
/*
* I 愛 the limitations on Solidity stack size!
*
* addresses
* 0..4 orderAddresses
* 5 tokenGet
* 6 tokenGive
* 7 user
*
* values
* 0..5 orderValues
* 6 fillTakerTokenAmount
* 7 amountGet
* 8 amountGive
* 9 expires
* 10 nonce
* 11 amount
* signature
* exchange then etherDelta
*/
function makeAtomicTrade(
address[8] addresses, uint[12] values,
uint8[2] v, bytes32[2] r, bytes32[2] s
) external onlyOwner {
makeExchangeTrade(addresses, values, v, r, s);
makeEtherDeltaTrade(addresses, values, v, r, s);
}
function makeEtherDeltaTrade(
address[8] addresses, uint[12] values,
uint8[2] v, bytes32[2] r, bytes32[2] s
) internal {
uint amount = values[11];
etherDelta.depositToken(addresses[5], values[7]);
etherDelta.trade(
addresses[5],
values[7],
addresses[6],
values[8],
values[9],
values[10],
addresses[7],
v[1],
r[1],
s[1],
amount
);
etherDelta.withdrawToken(addresses[6], values[8]);
}
function makeExchangeTrade(
address[8] addresses, uint[12] values,
uint8[2] v, bytes32[2] r, bytes32[2] s
) internal {
address[5] memory orderAddresses = [
addresses[0],
addresses[1],
addresses[2],
addresses[3],
addresses[4]
];
uint[6] memory orderValues = [
values[0],
values[1],
values[2],
values[3],
values[4],
values[5]
];
uint fillTakerTokenAmount = values[6];
exchange.fillOrKillOrder(orderAddresses, orderValues, fillTakerTokenAmount, v[0], r[0], s[0]);
}
}