aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src/current/tutorials/Arbitrage/Arbitrage.sol
blob: f355cfefc2ba780dabce6608c15397a6677fb140 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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]);
    }
}