| 1 | [ |
| 2 | "autonomous agent", |
| 3 | { |
| 4 | "doc_url": "https://oswap.io/oswap-triangular-arb.json", |
| 5 | "init": "{ |
| 6 | |
| 7 | $lib_aa = 'N7NRF3EZHGBK3KBCINKE7Z3GZGMFO4AS'; |
| 8 | |
| 9 | $asset = params.asset; |
| 10 | |
| 11 | $managers = var['managers'] OTHERWISE {}; |
| 12 | $is_authorized = trigger.address == params.owner OR $managers[trigger.address]; |
| 13 | |
| 14 | }", |
| 15 | "messages": { |
| 16 | "cases": [ |
| 17 | { |
| 18 | "if": "{ trigger.data.arb AND $is_authorized}", |
| 19 | "init": "{ |
| 20 | $share = trigger.data.share OTHERWISE 1; |
| 21 | $secondary_share = trigger.data.secondary_share OTHERWISE 1; |
| 22 | $precalculated = trigger.data.amount AND trigger.data.from; |
| 23 | if (!$precalculated) { |
| 24 | |
| 25 | $oswap_aas = trigger.data.oswap_aas; |
| 26 | $arb_info = ($lib_aa||'')#36.$calc_arb_params(this_address, $asset, $oswap_aas, $share, $secondary_share); |
| 27 | |
| 28 | $from = $arb_info.from; |
| 29 | $amount = $arb_info.amount; |
| 30 | $address = $arb_info.address; |
| 31 | $data = $arb_info.data; |
| 32 | |
| 33 | $pAB = $arb_info.pAB; |
| 34 | $pBC = $arb_info.pBC; |
| 35 | $pCA = $arb_info.pCA; |
| 36 | $assetA = $arb_info.assetA; |
| 37 | $assetB = $arb_info.assetB; |
| 38 | $assetC = $arb_info.assetC; |
| 39 | } |
| 40 | else { |
| 41 | $amount = trigger.data.amount; |
| 42 | $from = trigger.data.from; |
| 43 | $address = $oswap_aas[0]; |
| 44 | $data = { |
| 45 | final_price: trigger.data.final_pBA, |
| 46 | hops: [ |
| 47 | { |
| 48 | address: $oswap_aas[1], |
| 49 | change_address: this_address, |
| 50 | data: {final_price: trigger.data.final_pCB}, |
| 51 | }, |
| 52 | { |
| 53 | address: $oswap_aas[2], |
| 54 | change_address: this_address, |
| 55 | data: {final_price: trigger.data.final_pAC}, |
| 56 | }, |
| 57 | { |
| 58 | address: this_address, |
| 59 | }, |
| 60 | ] |
| 61 | }; |
| 62 | $pAB = 1/trigger.data.final_pBA; |
| 63 | $pBC = 1/trigger.data.final_pCB; |
| 64 | $pCA = 1/trigger.data.final_pAC; |
| 65 | $assetA = $asset; |
| 66 | $assetB = trigger.data.assetB; |
| 67 | $assetC = trigger.data.assetC; |
| 68 | } |
| 69 | }", |
| 70 | "messages": [ |
| 71 | { |
| 72 | "app": "payment", |
| 73 | "payload": { |
| 74 | "asset": "{$asset}", |
| 75 | "outputs": [ |
| 76 | { |
| 77 | "address": "{$address}", |
| 78 | "amount": "{ $amount }" |
| 79 | } |
| 80 | ] |
| 81 | } |
| 82 | }, |
| 83 | { |
| 84 | "app": "data", |
| 85 | "payload": "{$data}" |
| 86 | }, |
| 87 | { |
| 88 | "app": "state", |
| 89 | "state": "{ |
| 90 | $arb = { |
| 91 | from: $from, |
| 92 | pAB: $pAB, |
| 93 | pBC: $pBC, |
| 94 | pCA: $pCA, |
| 95 | assetA: $assetA, |
| 96 | assetB: $assetB, |
| 97 | assetC: $assetC, |
| 98 | oswap_aas: $oswap_aas, |
| 99 | sent: {}, |
| 100 | received: {}, |
| 101 | }; |
| 102 | $arb.sent[$asset] = $amount; |
| 103 | var['arb'] = $arb; |
| 104 | |
| 105 | response['sent_amount'] = $amount; |
| 106 | response['message'] = ($from == 'AB') |
| 107 | ? 'will arb by selling A to AB, then B to BC, then C to CA' |
| 108 | : 'will arb by selling A to AC, then C to CB, then B to BA'; |
| 109 | }" |
| 110 | } |
| 111 | ] |
| 112 | }, |
| 113 | { |
| 114 | "if": "{ |
| 115 | $arb = var['arb']; |
| 116 | if (!$arb) |
| 117 | return false; |
| 118 | $receivedA = trigger.output[[asset=$arb.assetA]]; |
| 119 | $receivedB = trigger.output[[asset=$arb.assetB]]; |
| 120 | $receivedC = trigger.output[[asset=$arb.assetC]]; |
| 121 | ($receivedA > 0 OR $receivedB > 0 OR $receivedC > 0) |
| 122 | }", |
| 123 | "init": "{ |
| 124 | }", |
| 125 | "messages": [ |
| 126 | { |
| 127 | "app": "state", |
| 128 | "state": "{ |
| 129 | $arb.received[$arb.assetA] = $arb.received[$arb.assetA] + $receivedA; |
| 130 | $arb.received[$arb.assetB] = $arb.received[$arb.assetB] + $receivedB; |
| 131 | $arb.received[$arb.assetC] = $arb.received[$arb.assetC] + $receivedC; |
| 132 | $change = $arb.from == 'AB' ? trigger.address != $arb.oswap_aas[2] : trigger.address != $arb.oswap_aas[0]; |
| 133 | if ($change){ |
| 134 | var['arb'] = $arb; |
| 135 | response['message'] = 'received the change from ' || trigger.address; |
| 136 | log('received the change from', trigger.address, $arb.received); |
| 137 | return; |
| 138 | } |
| 139 | |
| 140 | $sent = $arb.sent[$arb.assetA]; |
| 141 | $received = $arb.received[$arb.assetA] + $arb.received[$arb.assetB] / $arb.pAB + $arb.received[$arb.assetC] / $arb.pAB / $arb.pBC; |
| 142 | $profit = $received - $sent; |
| 143 | require($profit > 0, "unprofitable " || $arb.from || ": " || $received || " < " || $sent); |
| 144 | response['profit'] = $profit; |
| 145 | var['arb'] = false; |
| 146 | }" |
| 147 | } |
| 148 | ] |
| 149 | }, |
| 150 | { |
| 151 | "if": "{ trigger.data.exchange AND trigger.data.oswap_aa AND $is_authorized }", |
| 152 | "init": "{ |
| 153 | $oswap_aa = trigger.data.oswap_aa; |
| 154 | $share = trigger.data.share OTHERWISE 1; |
| 155 | $exch_info = ($lib_aa||'')#10.$calc_exchange_params(this_address, $oswap_aa, $asset, $share); |
| 156 | $data = $exch_info.data; |
| 157 | $assetB = $exch_info.assetB; |
| 158 | response['message'] = "will exchange "||$assetB||" to main asset"; |
| 159 | }", |
| 160 | "messages": [ |
| 161 | { |
| 162 | "app": "payment", |
| 163 | "payload": { |
| 164 | "asset": "{$assetB}", |
| 165 | "outputs": [ |
| 166 | { |
| 167 | "address": "{$oswap_aa}" |
| 168 | } |
| 169 | ] |
| 170 | } |
| 171 | }, |
| 172 | { |
| 173 | "app": "data", |
| 174 | "payload": "{$data}" |
| 175 | } |
| 176 | ] |
| 177 | }, |
| 178 | { |
| 179 | "if": "{ trigger.data.withdraw AND trigger.data.asset AND trigger.address == params.owner }", |
| 180 | "init": "{ |
| 181 | }", |
| 182 | "messages": [ |
| 183 | { |
| 184 | "app": "payment", |
| 185 | "payload": { |
| 186 | "asset": "{trigger.data.asset}", |
| 187 | "outputs": [ |
| 188 | { |
| 189 | "address": "{params.owner}", |
| 190 | "amount": "{ trigger.data.amount OTHERWISE '' }" |
| 191 | } |
| 192 | ] |
| 193 | } |
| 194 | } |
| 195 | ] |
| 196 | }, |
| 197 | { |
| 198 | "if": "{trigger.data.add_manager AND trigger.data.manager AND trigger.address == params.owner}", |
| 199 | "init": "{ |
| 200 | require(is_valid_address(trigger.data.manager), "invalid address"); |
| 201 | }", |
| 202 | "messages": [ |
| 203 | { |
| 204 | "app": "state", |
| 205 | "state": "{ |
| 206 | $managers[trigger.data.manager] = true; |
| 207 | var['managers'] = $managers; |
| 208 | response['message'] = 'added '||trigger.data.manager||' as manager'; |
| 209 | }" |
| 210 | } |
| 211 | ] |
| 212 | }, |
| 213 | { |
| 214 | "if": "{trigger.data.remove_manager AND trigger.data.manager AND trigger.address == params.owner}", |
| 215 | "init": "{ |
| 216 | require($managers[trigger.data.manager], "this address is not a manager"); |
| 217 | }", |
| 218 | "messages": [ |
| 219 | { |
| 220 | "app": "state", |
| 221 | "state": "{ |
| 222 | delete($managers, trigger.data.manager); |
| 223 | var['managers'] = $managers; |
| 224 | response['message'] = 'removed '||trigger.data.manager||' as manager'; |
| 225 | }" |
| 226 | } |
| 227 | ] |
| 228 | }, |
| 229 | { |
| 230 | "messages": [ |
| 231 | { |
| 232 | "app": "state", |
| 233 | "state": "{ |
| 234 | response['message'] = 'added'; |
| 235 | }" |
| 236 | } |
| 237 | ] |
| 238 | } |
| 239 | ] |
| 240 | } |
| 241 | } |
| 242 | ] |