P6DLF5MQPL3C6KDXP4SQO2MFVZ4XYT6T
[
"autonomous agent",
{
"messages": {
"cases": [
{
"if": "{trigger.data.withdraw AND trigger.data.asset AND trigger.data.amount}",
"init": "{
$key = 'balance_'||trigger.address||'_'||trigger.data.asset;
if (trigger.data.to){
if (!is_valid_address(trigger.data.to))
bounce("invalid withdrawal address: " || trigger.data.to);
$address = trigger.data.to;
}
else
$address = trigger.address;
if (trigger.data.amount > var[$key] + 0)
bounce("withdrawal amount too large, balance: " || (var[$key] + 0));
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{trigger.data.asset}",
"outputs": [
{
"address": "{$address}",
"amount": "{trigger.data.amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$key] = var[$key] - trigger.data.amount;
}"
}
]
},
{
"if": "{
$order1 = trigger.data.order1.signed_message;
$order2 = trigger.data.order2.signed_message;
if (!$order1.sell_asset OR !$order2.sell_asset)
return false;
if ($order1.sell_asset != $order2.buy_asset OR $order1.buy_asset != $order2.sell_asset)
bounce('assets do not match');
if ($order1.matcher != trigger.address)
bounce('wrong matcher in order1');
if ($order2.matcher != trigger.address)
bounce('wrong matcher in order2');
if ($order1.expiry_ts AND $order1.expiry_ts <= timestamp)
bounce("order1 expired");
if ($order2.expiry_ts AND $order2.expiry_ts <= timestamp)
bounce("order2 expired");
$sell_key1 = 'balance_' || $order1.address || '_' || $order1.sell_asset;
$sell_key2 = 'balance_' || $order2.address || '_' || $order2.sell_asset;
$id1 = sha256($order1.address || $order1.sell_asset || $order1.buy_asset || $order1.sell_amount || $order1.price || trigger.data.order1.last_ball_unit);
$id2 = sha256($order2.address || $order2.sell_asset || $order2.buy_asset || $order2.sell_amount || $order2.price || trigger.data.order2.last_ball_unit);
if (var['executed_' || $id1])
bounce('order1 already executed');
if (var['executed_' || $id2])
bounce('order2 already executed');
$amount_left1 = var['amount_left_' || $id1] otherwise $order1.sell_amount;
$amount_left2 = var['amount_left_' || $id2] otherwise $order2.sell_amount;
// check balances
if ($amount_left1 > var[$sell_key1] + 0)
bounce('not sufficient balance in sell asset to complete order1');
if ($amount_left2 > var[$sell_key2] + 0)
bounce('not sufficient balance in sell asset to complete order2');
// check if prices match
$buy_amount1 = round($amount_left1 * $order1.price);
if ($buy_amount1 > $amount_left2){ // order2 is the smaller one
$order_smaller = $order2;
$order_larger = $order1;
$id_smaller = $id2;
$id_larger = $id1;
$amount_left_smaller = $amount_left2;
$amount_left_larger = $amount_left1;
$buy_amount2 = round($amount_left2 * $order2.price);
$buy_amount_smaller = $buy_amount2;
$amount_sold2 = $amount_left2;
$amount_sold1 = $buy_amount2;
}
else{ // order1 is the smaller one
$order_smaller = $order1;
$order_larger = $order2;
$id_smaller = $id1;
$id_larger = $id2;
$amount_left_smaller = $amount_left1;
$amount_left_larger = $amount_left2;
$buy_amount_smaller = $buy_amount1;
$amount_sold1 = $amount_left1;
$amount_sold2 = $buy_amount1;
}
$expected_buy_amount_larger = round($buy_amount_smaller * $order_larger.price);
if ($expected_buy_amount_larger > $amount_left_smaller)
bounce("price mismatch: larger user doesn't like the price, he gets less than expects");
// matcher fees
$max_matcher_fee1 = round($order1.matcher_fee * $amount_sold1/$order1.sell_amount);
$max_matcher_fee2 = round($order2.matcher_fee * $amount_sold2/$order2.sell_amount);
$matcher_fee1 = (typeof(trigger.data.matcher_fee1) == 'boolean' AND !trigger.data.matcher_fee1 OR trigger.data.matcher_fee1 == 'default') ? $max_matcher_fee1 : trigger.data.matcher_fee1;
$matcher_fee2 = (typeof(trigger.data.matcher_fee2) == 'boolean' AND !trigger.data.matcher_fee2 OR trigger.data.matcher_fee2 == 'default') ? $max_matcher_fee2 : trigger.data.matcher_fee2;
// the formula will fail if matcher_fee1/matcher_fee2 is not a number
if ($matcher_fee1 > $max_matcher_fee1)
bounce('matcher_fee1 is too large');
if ($matcher_fee2 > $max_matcher_fee2)
bounce('matcher_fee2 is too large');
// affiliates
if ($order1.affiliate){
if (!$order1.affiliate_fee_asset)
bounce('no affiliate_fee_asset in order1');
if ($order1.affiliate_fee < 0) // will error if none or not a number
bounce('affiliate_fee < 0 in order1');
$affiliate_fee1 = round($order1.affiliate_fee * $amount_sold1/$order1.sell_amount);
}
if ($order2.affiliate){
if (!$order2.affiliate_fee_asset)
bounce('no affiliate_fee_asset in order2');
if ($order2.affiliate_fee < 0) // will error if none or not a number
bounce('affiliate_fee < 0 in order2');
$affiliate_fee2 = round($order2.affiliate_fee * $amount_sold2/$order2.sell_amount);
}
if (!is_valid_signed_package(trigger.data.order1, $order1.address))
bounce('bad signature of order1');
if (!is_valid_signed_package(trigger.data.order2, $order2.address))
bounce('bad signature of order2');
true
}",
"messages": [
{
"app": "state",
"state": "{
$buy_key1 = 'balance_' || $order1.address || '_' || $order1.buy_asset;
$buy_key2 = 'balance_' || $order2.address || '_' || $order2.buy_asset;
var[$sell_key1] -= $amount_sold1;
var[$sell_key2] -= $amount_sold2;
var[$buy_key1] += $amount_sold2;
var[$buy_key2] += $amount_sold1;
// matcher fees
$matcher_fee_user_key1 = 'balance_' || $order1.address || '_' || $order1.matcher_fee_asset;
$matcher_fee_user_key2 = 'balance_' || $order2.address || '_' || $order2.matcher_fee_asset;
$matcher_fee_matcher_key1 = 'balance_' || $order1.matcher || '_' || $order1.matcher_fee_asset;
$matcher_fee_matcher_key2 = 'balance_' || $order2.matcher || '_' || $order2.matcher_fee_asset;
var[$matcher_fee_matcher_key1] += $matcher_fee1;
var[$matcher_fee_matcher_key2] += $matcher_fee2;
var[$matcher_fee_user_key1] -= $matcher_fee1;
var[$matcher_fee_user_key2] -= $matcher_fee2;
if (var[$matcher_fee_user_key1] < 0)
bounce("not enough user1 balance for matcher fees");
if (var[$matcher_fee_user_key2] < 0)
bounce("not enough user2 balance for matcher fees");
// fees can be negative
if (var[$matcher_fee_matcher_key1] < 0)
bounce("not enough matcher order1.matcher_fee_asset balance for matcher fees");
if (var[$matcher_fee_matcher_key2] < 0)
bounce("not enough matcher order2.matcher_fee_asset balance for matcher fees");
// affiliate fees
if ($order1.affiliate AND $affiliate_fee1){
$affiliate_fee_user_key1 = 'balance_' || $order1.address || '_' || $order1.affiliate_fee_asset;
$affiliate_fee_affiliate_key1 = 'balance_' || $order1.affiliate || '_' || $order1.affiliate_fee_asset;
var[$affiliate_fee_user_key1] -= $affiliate_fee1;
var[$affiliate_fee_affiliate_key1] += $affiliate_fee1;
if (var[$affiliate_fee_user_key1] < 0)
bounce("not enough user1 balance for affiliate fees");
}
if ($order2.affiliate AND $affiliate_fee2){
$affiliate_fee_user_key2 = 'balance_' || $order2.address || '_' || $order2.affiliate_fee_asset;
$affiliate_fee_affiliate_key2 = 'balance_' || $order2.affiliate || '_' || $order2.affiliate_fee_asset;
var[$affiliate_fee_user_key2] -= $affiliate_fee2;
var[$affiliate_fee_affiliate_key2] += $affiliate_fee2;
if (var[$affiliate_fee_user_key2] < 0)
bounce("not enough user2 balance for affiliate fees");
}
// AA fees
$aa_fee = 1000;
$base_key1 = 'balance_' || $order1.address || '_base';
$base_key2 = 'balance_' || $order2.address || '_base';
var[$base_key1] -= $aa_fee;
var[$base_key2] -= $aa_fee;
if (var[$base_key1] < 0 OR var[$base_key2] < 0)
bounce('not enough balance for AA fees');
var['executed_' || $id_smaller] = 1;
$new_amount_left_larger = $amount_left_larger - $buy_amount_smaller;
if ($new_amount_left_larger < 0)
bounce("panic: new_amount_left_larger < 0");
if ($new_amount_left_larger)
var['amount_left_' || $id_larger] = $new_amount_left_larger;
else
var['executed_' || $id_larger] = 1;
// parsable response for transaction log
response[$order1.address || '_' || $order1.sell_asset] = -$amount_sold1;
response[$order2.address || '_' || $order2.buy_asset] = $amount_sold1;
response[$order1.address || '_' || $order1.buy_asset] = $amount_sold2;
response[$order2.address || '_' || $order2.sell_asset] = -$amount_sold2;
}"
}
]
},
{
"if": "{!trigger.data}",
"messages": [
{
"app": "state",
"state": "{
$asset = trigger.output[[asset!=base]].asset;
if ($asset == 'ambiguous')
bounce('ambiguous asset');
if (trigger.data.to){
if (!is_valid_address(trigger.data.to))
bounce("invalid deposit address: " || trigger.data.to);
$address = trigger.data.to;
}
else
$address = trigger.address;
$base_key = 'balance_'||$address||'_'||'base';
var[$base_key] = var[$base_key] + trigger.output[[asset=base]];
$response_base = trigger.output[[asset=base]] || ' bytes';
if ($asset != 'none'){
$asset_key = 'balance_'||$address||'_'||$asset;
var[$asset_key] = var[$asset_key] + trigger.output[[asset=$asset]];
$response_asset = ' and ' || trigger.output[[asset=$asset]] || ' of ' || $asset;
}
response['message'] = 'accepted coins: ' || $response_base || ($response_asset otherwise '');
}"
}
]
}
]
}
}
]
MCI: 1153737 Not bounced Response unit: Response: {} MCI: 1153689 Not bounced Response unit: Response: {} MCI: 1153646 Not bounced Response unit: Response: {} MCI: 1152893 Not bounced Response unit: Response: {} MCI: 1152837 Not bounced Response unit: Response: {} MCI: 1142442 Not bounced Response: {
"responseVars": {
"EJC4A7WQGHEZEKW6RLO7F26SAR4LAQBU_base": -50000000,
"EDMS22PYWN5NE7F34R5CLNTJSVNLLGLS_base": 50000000,
"EJC4A7WQGHEZEKW6RLO7F26SAR4LAQBU_UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw=": 1000000,
"EDMS22PYWN5NE7F34R5CLNTJSVNLLGLS_UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw=": -1000000
},
"error": "no messages after filtering"
} MCI: 1142432 Not bounced Response: {
"responseVars": {
"EJC4A7WQGHEZEKW6RLO7F26SAR4LAQBU_base": -50000000,
"EDMS22PYWN5NE7F34R5CLNTJSVNLLGLS_base": 50000000,
"EJC4A7WQGHEZEKW6RLO7F26SAR4LAQBU_UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw=": 1000000,
"EDMS22PYWN5NE7F34R5CLNTJSVNLLGLS_UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw=": -1000000
},
"error": "no messages after filtering"
} MCI: 1142157 Not bounced Response: {
"responseVars": {
"EDMS22PYWN5NE7F34R5CLNTJSVNLLGLS_UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw=": -2000000,
"EJC4A7WQGHEZEKW6RLO7F26SAR4LAQBU_UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw=": 2000000,
"EDMS22PYWN5NE7F34R5CLNTJSVNLLGLS_base": 100000000,
"EJC4A7WQGHEZEKW6RLO7F26SAR4LAQBU_base": -100000000
},
"error": "no messages after filtering"
} MCI: 1142083 Not bounced Response: {
"responseVars": {
"message": "accepted coins: 10000 bytes and 30000000 of UccpQo12uLmufihkzdK7Kcrb5BlHp8GcMrSEA7NVdNw="
},
"error": "no messages after filtering"
} MCI: 1142078 Not bounced Response: {
"responseVars": {
"message": "accepted coins: 1000000000 bytes"
},
"error": "no messages after filtering"
} Show transactions in assets: All bytes USDC
No transactions found, it may be worth changing the filter
Unit ID
Date
From
Direction
To
Amount
05.12.2019 11:21:02
P6DLF5MQPL3C6KDXP4SQO2MFVZ4XYT6T
out
05.12.2019 11:21:02
in
P6DLF5MQPL3C6KDXP4SQO2MFVZ4XYT6T
05.12.2019 10:52:35
P6DLF5MQPL3C6KDXP4SQO2MFVZ4XYT6T
out
05.12.2019 10:52:35
in
P6DLF5MQPL3C6KDXP4SQO2MFVZ4XYT6T
05.12.2019 10:39:07
P6DLF5MQPL3C6KDXP4SQO2MFVZ4XYT6T
out