[
"autonomous agent",
{
"init": "{
$owner = 'JBGMJI7XSKLKNHZF26BUBWHVUZSDV3P5';
$stablecoin_issuer = '46RD24PCL22DMQSPQWRJPHFV24CH7SLA';
$addr = trigger.address;
$base_inp = trigger.output[[asset=base]] - 700;
if(!var['owner'])
return;
$base_asset = var['base_asset'];
$last_coin_key = 'last_used_' || $addr;
if($base_inp <= 0)
bounce('not enough bytes for fees');
if(trigger.output[[asset!=base]].asset != 'none'){
if(trigger.output[[asset!=base]].asset != var['base_asset']){
$asset = trigger.output[[asset!=base]].asset;
if($asset == 'ambiguous'){
bounce('only 1 asset per tx');
}
if(trigger.output[[asset!=base]] == 0){
bounce('zero asset tx');
}
}
if($asset){
$asset_des = $base_asset;
$asset_inp = trigger.output[[asset!=base]];
$name = var['reg_'||$asset];
}
else{
if(!trigger.data.name)
bounce('you must use a name');
$name = trigger.data.name;
$asset_des = var['name_'||trigger.data.name];
$base_asset_inp = trigger.output[[asset=$asset_des]];
}
}
else{
if(!trigger.data.withdraw){
bounce('there must be at least one asset');
}
}
$registered = $asset ? var['reg_'||$asset] : $asset_des;
if(!$registered){
if(trigger.data.register_asset){
return;
}
else{
bounce('asset must be registered first');
}
}
$ratio_key = $name || '_last_price';
if(!var[$ratio_key] and !trigger.data.price){
bounce('price must be defined before first exchange');
}
if(trigger.data.price){
$ratio = round(trigger.data.price);//microUSD per 1 asset
if($ratio <= 0){
bounce('ratio not allowed');
}
}
else{
$ratio = var[$ratio_key];
}
$base_key = $name || '_' || $addr || '_' || $ratio || '_base';
$total_key = $name || '_' || $ratio || '_total_base';
$exch_key = $name || '_' || $ratio || 'exchanged_base';
$asset_key = $name || '_' || $addr || '_' || $ratio;
$total_asset_key = $name || '_' || $ratio || '_total_asset';
$exch_asset_key = $name || '_' || $ratio || 'exchanged_asset';
$max_b_to_exchange = var[$total_key] - var[$exch_key];
$max_a_to_exchange = var[$total_asset_key] - var[$exch_asset_key];
$base_inp_round = $base_inp_asset;
$base_inp_in_asset = ($base_inp_round - ($base_inp_round % $ratio)/ $ratio);
$asset_inp_in_base_asset = $asset_inp * $ratio;
if($asset){
if($max_b_to_exchange and $max_b_to_exchange > 0 and !trigger.data.withdraw){
//exchange
if($asset_inp_in_bytes > $max_b_to_exchange){
//partial exchange till empty,return rest and bfees
$base_amount = $max_b_to_exchange;
$asset_amount = (($asset_inp_in_bytes - $max_b_to_exchange) - (($asset_inp_in_bytes - $max_b_to_exchange) % $ratio)) / $ratio;
}
else{
//full exchange until empty,return bfees
$base_amount = $asset_inp_in_bytes;
$asset_amount = 0;
}
}
else{
if(!trigger.data.cancel)
$deposit = true;
}
}
else{
if($max_a_to_exchange and $max_a_to_exchange > 0 and !trigger.data.withdraw){
//exchange
if($base_inp_in_asset > $max_a_to_exchange){
//partial exchange till empty,return rest
$asset_amount = $max_a_to_exchange;
$base_amount = ($base_inp_in_asset - $max_a_to_exchange) * $ratio;
}
else{
if($base_inp_in_asset == 0)
bounce('Not enough funds, try with higher amount');
//full exchange until empty
$asset_amount = $base_inp_in_asset;
$base_amount = 0;
}
}
else{
if(!trigger.data.cancel)
$deposit = true;
}
}
}",
"messages": {
"cases": [
{
"if": "{//init
!var['owner']
}",
"messages": [
{
"if": "{!var['base_asset']}",
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$stablecoin_issuer}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "state",
"state": "{
if(!var['base_asset']){
var['base_asset'] = true;
}
else{
var['base_asset'] = var[$stablecoin_issuer]['asset'];
var['reg_'||var['base_asset']] = 'microUSD';
var['name_'||'microUSD'] = var['base_asset'];
var['owner'] = $owner;
}
}"
}
]
},
{
"if": "{//register asset name
trigger.data.register_asset and $asset
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{$asset}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$asset_inp}"
}
]
}
},
{
"app": "state",
"state": "{
$namet = trigger.data.name;
if($namet){
if(var['name_'||$namet]){
bounce('name already chosen');
}
}
else{
bounce('no name defined');
}
var['reg_'||$asset] = $namet;
var['name_'||$namet] = $asset;
response['message'] = 'asset registered with name '||$namet;
}"
}
]
},
{
"if": "{// let retire exchanged amount (asset)
var[$exch_asset_key] and var[$base_key] and var[$exch_asset_key] > 0 and var[$base_key] > 0
}",
"init": "{
$max_to_retire = (var[$base_key] / $ratio) - (var[$base_key] % $ratio);
if(var[$exch_asset_key] <= $max_to_retire){
$retire_amount = var[$exch_asset_key];
}
else{
$retire_amount = $max_to_retire;
}
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$asset_ct}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$retire_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$last_coin_key] = $name;
var[$total_asset_key] -= $retire_amount;
var[$exch_asset_key] -= $retire_amount;
var[$base_key] -= $retire_amount * $ratio;
response['message'] = 'retired exchanged amount ('||$name||') at '||$ratio||' microUSD per token';
}"
}
]
},
{
"if": "{// let retire exchanged amount (microUSD)
var[$exch_key] and var[$asset_key] and var[$exch_key] > 0 and var[$asset_key] > 0
}",
"init": "{
$max_to_retire = var[$asset_key] * $ratio;
if(var[$exch_key] <= $max_to_retire){
$retire_amount = var[$exch_key];
}
else{
$retire_amount = $max_to_retire;
}
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$base_asset}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$retire_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$last_coin_key] = $name;
var[$total_key] -= $retire_amount;
var[$exch_key] -= $retire_amount;
var[$asset_key] -= $retire_amount / $ratio;
response['message'] = 'retired exchanged amount (microUSD) at '||$ratio||' microUSD per token';
}"
}
]
},
{
"if": "{//exchange asset x microUSD
$asset and $base_amount and !var[$base_key]
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$base_asset}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_amount}"
}
]
}
},
{
"if": "{$asset_amount > 0}",
"app": "payment",
"payload": {
"asset": "{$asset_ct}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$asset_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$total_asset_key] += $asset_inp - $asset_amount;
var[$exch_asset_key] += $asset_inp - $asset_amount;
var[$total_key] -= $base_amount;
var[$ratio_key] = $ratio;
var[$last_coin_key] = $name;
response['message'] = 'sold '||($asset_inp - $asset_amount)||' '||$name||' for '||($base_amount)||' microUSD';
}"
}
]
},
{
"if": "{//exchange microUSD x asset
!$asset and $asset_amount and !var[$asset_key]
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"if": "{$base_amount > 0}",
"app": "payment",
"payload": {
"asset": "{$base_asset}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_amount}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$asset_ct}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$asset_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$total_key] += $base_inp_round - $base_amount;
var[$exch_key] += $base_inp_round - $base_amount;
var[$total_asset_key] -= $asset_amount;
var[$ratio_key] = $ratio;
var[$last_coin_key] = $name;
response['message'] = 'bought '||($asset_amount)||' '||$name||' for '||($base_inp_round - $base_amount)||' microUSD';
}"
}
]
},
{
"if": "{// let cancel order (asset)
trigger.data.withdraw and var[$asset_key] and var[$asset_key] > 0
}",
"init": "{
if($max_a_to_exchange <= 0){
bounce('Not allowed');
}
if($max_a_to_exchange <= var[$asset_key]){
$retire_amount = $max_a_to_exchange;
}
else{
$retire_amount = var[$asset_key];
}
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$asset_ct}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$retire_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$total_asset_key] -= $retire_amount;
var[$asset_key] -= $retire_amount;
var[$last_coin_key] = $name;
response['message'] = 'canceled order (sell '||$name||' at '||$ratio||' microUSD per token)';
}"
}
]
},
{
"if": "{// let cancel order (microUSD)
trigger.data.withdraw and var[$base_key] and var[$base_key] > 0
}",
"init": "{
if($max_b_to_exchange <= 0){
bounce('Not allowed');
}
if($max_b_to_exchange <= var[$base_key]){
$retire_amount = $max_b_to_exchange ;
}
else{
$retire_amount = var[$base_key];
}
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "payment",
"payload": {
"asset": "{$base_asset}",
"outputs": [
{
"address": "{$addr}",
"amount": "{$retire_amount}"
}
]
}
},
{
"app": "state",
"state": "{
var[$total_key] -= $retire_amount;
var[$base_key] -= $retire_amount;
var[$last_coin_key] = $name;
response['message'] = 'canceled order (buy '||$name||' at '||$ratio||' microUSD per token)';
}"
}
]
},
{
"if": "{
if(!$deposit){
bounce("Deposit not allowed, please cancel order first");
}
$deposit
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$addr}",
"amount": "{$base_inp}"
}
]
}
},
{
"app": "state",
"state": "{
var[$last_coin_key] = $name;
if($asset){
var[$total_asset_key] += $asset_inp;
var[$asset_key] += $asset_inp;
response['message'] = 'deposited '||$asset_inp||' '||$name||' to sell at '||$ratio||' microUSD per token';
}
else{
var[$total_key] += $base_inp_round;
var[$base_key] += $base_inp_round;
response['message'] = 'deposited '||$base_inp_round||' bytes to buy '||$name||' at '||$ratio||' microUSD per token';
}
}"
}
]
}
]
}
}
]