[
"autonomous agent",
{
"doc_url": "https://ostable.org/bonded-stablecoin-deposits.json",
"init": "{
// reserve
$interest_asset = params.interest_asset;
$curve_aa = params.curve_aa;
// tokens
$asset = var['asset'];
$interest_rate = var[$curve_aa]['interest_rate'];
$term = (timestamp - var[$curve_aa]['rate_update_ts']) / (360 * 24 * 3600); // in years
$growth_factor = var[$curve_aa]['growth_factor'] * (1 + $interest_rate)^$term;
}",
"messages": {
"cases": [
{
"if": "{ trigger.data.define AND !$asset }",
"messages": [
{
"app": "asset",
"payload": {
"is_private": false,
"is_transferrable": true,
"auto_destroy": false,
"fixed_denominations": false,
"issued_by_definer_only": true,
"cosigned_by_definer": false,
"spender_attested": false
}
},
{
"if": "{trigger.data.factory}",
"app": "data",
"payload": {
"write_stable_asset": 1,
"curve_aa": "{$curve_aa}"
}
},
{
"if": "{trigger.data.factory}",
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{trigger.data.factory}"
}
]
}
},
{
"app": "state",
"state": "{
var['asset'] = response_unit;
response['asset'] = response_unit;
}"
}
]
},
{
"if": "{ $asset AND trigger.output[[asset=$interest_asset]] > 0 }",
"init": "{
if (exists(trigger.data.interest_recipient) AND !is_valid_address(trigger.data.interest_recipient))
bounce("bad address of interest recipient");
if (exists(trigger.data.to) AND !is_valid_address(trigger.data.to))
bounce("bad to-address");
if (exists(trigger.data.owner) AND !is_valid_address(trigger.data.owner))
bounce("bad owner address");
$to = trigger.data.to OTHERWISE trigger.address;
$owner = trigger.data.owner OTHERWISE $to;
$deposit_amount = trigger.output[[asset=$interest_asset]];
$stable_amount = floor($deposit_amount * $growth_factor);
$id = trigger.unit;
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{$asset}",
"outputs": [
{
"address": "{$to}",
"amount": "{ $stable_amount }"
}
]
}
},
{
"if": "{trigger.data.to AND is_aa(trigger.data.to)}",
"app": "data",
"payload": {
"to": "{trigger.address}"
}
},
{
"app": "state",
"state": "{
response['id'] = $id;
var['deposit_' || $id || '_amount'] = $deposit_amount;
var['deposit_' || $id || '_stable_amount'] = $stable_amount;
var['deposit_' || $id || '_owner'] = $owner;
if (trigger.data.interest_recipient)
var['deposit_' || $id || '_interest_recipient'] = trigger.data.interest_recipient;
var['supply'] += $stable_amount;
}"
}
]
},
{
"if": "{ $asset AND trigger.output[[asset=$asset]] > 0 AND trigger.data.id }",
"init": "{
if (exists(trigger.data.to) AND !is_valid_address(trigger.data.to))
bounce("bad to-address");
$to = trigger.data.to OTHERWISE trigger.address;
$id = trigger.data.id;
if (var['deposit_' || $id || '_owner'] != trigger.address)
bounce("you are not the owner");
$deposit_amount = var['deposit_' || $id || '_amount'];
$stable_amount = var['deposit_' || $id || '_stable_amount'];
$interest_recipient = var['deposit_' || $id || '_interest_recipient'];
if ($interest_recipient AND $interest_recipient != trigger.address){
$new_stable_amount = floor($deposit_amount * $growth_factor);
$interest = $new_stable_amount - $stable_amount;
$expected_stable_amount = $new_stable_amount;
}
else
$expected_stable_amount = $stable_amount;
if ($expected_stable_amount != trigger.output[[asset=$asset]])
bounce("expected " || $expected_stable_amount);
$to_aa = trigger.data.to AND is_aa(trigger.data.to);
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{$interest_asset}",
"outputs": [
{
"address": "{$to}",
"amount": "{ $deposit_amount }"
}
]
}
},
{
"if": "{$to_aa}",
"app": "data",
"payload": {
"to": "{trigger.address}"
}
},
{
"if": "{$to_aa}",
"app": "payment",
"payload": {
"asset": "base",
"outputs": [
{
"address": "{$to}",
"amount": 2000
}
]
}
},
{
"if": "{$interest}",
"app": "payment",
"payload": {
"asset": "{$asset}",
"outputs": [
{
"address": "{$interest_recipient}",
"amount": "{ $interest }"
}
]
}
},
{
"app": "state",
"state": "{
var['deposit_' || $id || '_amount'] = false;
var['deposit_' || $id || '_stable_amount'] = false;
var['deposit_' || $id || '_owner'] = false;
var['deposit_' || $id || '_interest_recipient'] = false;
var['supply'] -= $stable_amount;
}"
}
]
},
{
"if": "{ $asset AND trigger.data.id AND trigger.data.change_interest_recipient }",
"init": "{
// if trigger.data.interest_recipient is not specified then the owner wants to get interest himself
if (exists(trigger.data.interest_recipient) AND !is_valid_address(trigger.data.interest_recipient))
bounce("bad address of new interest recipient");
$id = trigger.data.id;
$deposit_amount = var['deposit_' || $id || '_amount'];
if (!$deposit_amount)
bounce("deposit not found");
if (var['deposit_' || $id || '_owner'] != trigger.address)
bounce("you are not the owner");
$interest_recipient = var['deposit_' || $id || '_interest_recipient'];
$old_recipient = $interest_recipient OTHERWISE trigger.address;
$new_stable_amount = floor($deposit_amount * $growth_factor);
$interest = $new_stable_amount - var['deposit_' || $id || '_stable_amount'];
if ($interest < 0)
bounce("negative interest?");
}",
"messages": [
{
"if": "{$interest > 0}",
"app": "payment",
"payload": {
"asset": "{$asset}",
"outputs": [
{
"address": "{$old_recipient}",
"amount": "{ $interest }"
}
]
}
},
{
"app": "state",
"state": "{
var['deposit_' || $id || '_stable_amount'] = $new_stable_amount;
var['deposit_' || $id || '_interest_recipient'] = trigger.data.interest_recipient; // can be false to redirect interest to self
var['supply'] += $interest;
}"
}
]
},
{
"if": "{ $asset AND trigger.data.id }",
"init": "{
$id = trigger.data.id;
$deposit_amount = var['deposit_' || $id || '_amount'];
if (!$deposit_amount)
bounce("deposit not found");
$interest_recipient = var['deposit_' || $id || '_interest_recipient'];
$recipient = $interest_recipient OTHERWISE trigger.address;
// if interest recipient is not assigned, only the owner can trigger an interest payment
if (!$interest_recipient AND var['deposit_' || $id || '_owner'] != trigger.address)
bounce("you are not the owner");
$new_stable_amount = floor($deposit_amount * $growth_factor);
$interest = $new_stable_amount - var['deposit_' || $id || '_stable_amount'];
if ($interest < 0)
bounce("negative interest?");
if ($interest == 0)
bounce("0 interest accrued");
}",
"messages": [
{
"app": "payment",
"payload": {
"asset": "{$asset}",
"outputs": [
{
"address": "{$recipient}",
"amount": "{ $interest }"
}
]
}
},
{
"app": "state",
"state": "{
var['deposit_' || $id || '_stable_amount'] = $new_stable_amount;
var['supply'] += $interest;
}"
}
]
}
]
}
}
]