Created
April 20, 2020 23:30
-
-
Save tonyofbyteball/ca071b74babdb368c0435fdff94f6858 to your computer and use it in GitHub Desktop.
Uniswap-like market maker with single-token contributions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
init: `{ | |
$asset = 'n9y3VomFeWFeZZ2PcSEcmyBb/bI7kzZduBJigNetnkY='; | |
$mm_asset = var['mm_asset']; | |
}`, | |
messages: { | |
cases: [ | |
{ // define share asset | |
if: `{ trigger.data.define AND !$mm_asset }`, | |
messages: [ | |
{ | |
app: 'asset', | |
payload: { | |
// without cap | |
is_private: false, | |
is_transferrable: true, | |
auto_destroy: false, | |
fixed_denominations: false, | |
issued_by_definer_only: true, | |
cosigned_by_definer: false, | |
spender_attested: false, | |
} | |
}, | |
{ | |
app: 'state', | |
state: `{ | |
var['mm_asset'] = response_unit; | |
response['mm_asset'] = response_unit; | |
}` | |
} | |
] | |
}, | |
{ // invest in MM | |
if: `{ | |
$base_amount = trigger.output[[asset=base]]; | |
$asset_amount = trigger.output[[asset=$asset]]; | |
$both = $base_amount > 1e5 AND $asset_amount > 0; | |
$asset_only = $base_amount == 1e4 AND $asset_amount > 0; | |
$base_only = $base_amount > 1e5 AND $asset_amount == 0; | |
$mm_asset AND ($both OR trigger.data.contribute AND ($asset_only OR $base_only)) | |
}`, | |
init: `{ | |
$asset_balance = balance[$asset] - $asset_amount; | |
$bytes_balance = balance[base] - $base_amount; | |
if ($asset_balance == 0 OR $bytes_balance == 0){ // initial deposit | |
if (!$both) | |
bounce("initial contribution must have both tokens"); | |
$issue_amount = balance[base]; | |
return; | |
} | |
if ($both){ | |
$current_ratio = $asset_balance / $bytes_balance; | |
$expected_asset_amount = round($current_ratio * $base_amount); | |
if ($expected_asset_amount != $asset_amount) | |
bounce('wrong ratio of amounts, expected ' || $expected_asset_amount || ' of asset'); | |
$investor_share_of_prev_balance = $base_amount / $bytes_balance; | |
} | |
else if ($asset_only){ | |
$investor_share_of_prev_balance = sqrt(1 + $asset_amount/$asset_balance) - 1; | |
} | |
else if ($base_only){ | |
$investor_share_of_prev_balance = sqrt(1 + $base_amount/$bytes_balance) - 1; | |
} | |
$issue_amount = round($investor_share_of_prev_balance * var['mm_asset_outstanding']); | |
}`, | |
messages: [ | |
{ | |
app: 'payment', | |
payload: { | |
asset: "{$mm_asset}", | |
outputs: [ | |
{address: "{trigger.address}", amount: "{ $issue_amount }"} | |
] | |
} | |
}, | |
{ | |
app: 'state', | |
state: `{ | |
var['mm_asset_outstanding'] += $issue_amount; | |
}` | |
}, | |
] | |
}, | |
{ // divest MM shares | |
// (user is already paying 10000 bytes bounce fee which is a divest fee) | |
// the price slightly moves due to fees received and paid in bytes | |
if: `{$mm_asset AND trigger.output[[asset=$mm_asset]]}`, | |
init: `{ | |
$mm_asset_amount = trigger.output[[asset=$mm_asset]]; | |
$investor_share = $mm_asset_amount / var['mm_asset_outstanding']; | |
}`, | |
messages: [ | |
{ | |
app: 'payment', | |
payload: { | |
asset: "{$asset}", | |
outputs: [ | |
{address: "{trigger.address}", amount: "{ round($investor_share * balance[$asset]) }"} | |
] | |
} | |
}, | |
{ | |
app: 'payment', | |
payload: { | |
asset: "base", | |
outputs: [ | |
{address: "{trigger.address}", amount: "{ round($investor_share * balance[base]) }"} | |
] | |
} | |
}, | |
{ | |
app: 'state', | |
state: `{ | |
var['mm_asset_outstanding'] -= trigger.output[[asset=$mm_asset]]; | |
}` | |
}, | |
] | |
}, | |
{ // exchange bytes to asset | |
if: `{trigger.output[[asset=base]] > 1e5 AND trigger.output[[asset=$asset]] == 0 AND var['mm_asset_outstanding']}`, | |
init: `{ | |
$asset_balance = balance[$asset] - trigger.output[[asset=$asset]]; | |
$bytes_balance = balance[base] - trigger.output[[asset=base]]; | |
// other formula can be used for product, e.g. $asset_balance * $bytes_balance ^ 2 | |
$p = $asset_balance * $bytes_balance; | |
$new_asset_balance = round($p / balance[base]); | |
$amount = $asset_balance - $new_asset_balance; // we can deduct exchange fees here | |
}`, | |
messages: [ | |
{ | |
app: 'payment', | |
payload: { | |
asset: "{$asset}", | |
outputs: [ | |
{address: "{trigger.address}", amount: "{ $amount }"} | |
] | |
} | |
}, | |
] | |
}, | |
{ // exchange asset to bytes | |
if: `{trigger.output[[asset=$asset]] > 0 AND var['mm_asset_outstanding']}`, | |
init: `{ | |
$asset_balance = balance[$asset] - trigger.output[[asset=$asset]]; | |
$bytes_balance = balance[base] - trigger.output[[asset=base]]; // 10Kb fee | |
// other formula can be used for product, e.g. $asset_balance * $bytes_balance ^ 2 | |
$p = $asset_balance * $bytes_balance; | |
$new_bytes_balance = round($p / balance[$asset]); | |
$amount = $bytes_balance - $new_bytes_balance; // we can deduct exchange fees here | |
}`, | |
messages: [ | |
{ | |
app: 'payment', | |
payload: { | |
asset: "base", | |
outputs: [ | |
{address: "{trigger.address}", amount: "{ $amount }"} | |
] | |
} | |
}, | |
] | |
}, | |
] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment