@version 1
condition triggered_by: transaction, on: add_pool(token1_address, token2_address, pool_creation_address), as: [
type: "transfer",
content: (
valid? = false
token1_address = String.to_uppercase(token1_address)
token2_address = String.to_uppercase(token2_address)
pool_creation_address = String.to_hex(pool_creation_address)
pool_exists? = get_pool_addresses(token1_address, token2_address) != nil
if token1_address != token2_address && !pool_exists? do
# Could create a new function Chain.get_transactions(list_of_address)
pool_transaction = Chain.get_transaction(pool_creation_address)
# Ensure tokens exists and lp token definition is good
valid_token1? = valid_token?(token1_address)
valid_token2? = valid_token?(token2_address)
valid_definition? = false
if valid_token1? && valid_token2? && pool_transaction != nil && pool_transaction.type == "token" do
expected_content = Contract.call_function(
0x000086e60124c986ebcaa5affb7a3db8213072a132233fe61cf45651fdcf3c4cecea,
"get_lp_token_definition",
[token1_address, token2_address]
)
valid_definition? = Json.parse(pool_transaction.content) == Json.parse(expected_content)
end
valid_code? = false
pool_genesis_address = nil
if valid_definition? do
# Ensure code is valid
pool_genesis_address = Chain.get_genesis_address(pool_creation_address)
expected_code = Contract.call_function(
0x000086e60124c986ebcaa5affb7a3db8213072a132233fe61cf45651fdcf3c4cecea,
"get_pool_code",
[token1_address, token2_address, pool_genesis_address, pool_creation_address]
)
valid_code? = Code.is_same?(pool_transaction.code, expected_code)
end
if valid_code? do
# Ensure liquidity is provided to the pool
valid? = List.in?(transaction.recipients, pool_genesis_address)
end
end
valid?
)
]
actions triggered_by: transaction, on: add_pool(token1_address, token2_address, pool_creation_address) do
token1_address = String.to_uppercase(token1_address)
token2_address = String.to_uppercase(token2_address)
pool_creation_address = String.to_hex(pool_creation_address)
pool_genesis_address = Chain.get_genesis_address(pool_creation_address)
pool_id = get_pool_id(token1_address, token2_address)
pools = State.get("pools", Map.new())
pool_data = [
address: pool_genesis_address,
lp_token_address: pool_creation_address
]
pools = Map.set(pools, pool_id, pool_data)
State.set("pools", pools)
end
condition triggered_by: transaction, on: add_farm(lp_token, start_date, end_date, reward_token, farm_creation_address), as: [
address: (
# Farm can only be created by the master chain of the dex
# Transaction is not yet validated so we need to use previous address
# to get the genesis address
previous_address = Chain.get_previous_address(transaction)
Chain.get_genesis_address(previous_address) == 0x0000e46f8e90074ddf1dfc46385e07d826d35251f3a7b7ff65ad6f7e4b138aff7c10
),
content: (
lp_token = String.to_hex(lp_token)
reward_token = String.to_uppercase(reward_token)
farm_creation_address = String.to_hex(farm_creation_address)
# LP token should be listed on dex
lp_token_exists? = false
pools = State.get("pools", Map.new())
for pool in Map.values(pools) do
if String.to_hex(pool.lp_token_address) == lp_token do
lp_token_exists? = true
end
end
# Start date should be between 2 hours and 1 week from now
# End date should be between 1 month (30 days) and 1 year (365 days) from start date
valid_date? = false
if lp_token_exists? do
now = Time.now()
valid_start_date? = now + 7200 <= start_date && now + 604800 >= start_date
valid_end_date? = start_date + 2592000 <= end_date && start_date + 31536000 >= end_date
valid_date? = valid_start_date? && valid_end_date?
end
# Ensure farm code is valid
valid_code? = false
farm_genesis_address = nil
if valid_date? do
farm_transaction = Chain.get_transaction(farm_creation_address)
if farm_transaction != nil && farm_transaction.type == "contract" do
farm_genesis_address = Chain.get_genesis_address(farm_creation_address)
expected_code = Contract.call_function(
0x000086e60124c986ebcaa5affb7a3db8213072a132233fe61cf45651fdcf3c4cecea,
"get_farm_code",
[lp_token, start_date, end_date, reward_token, farm_genesis_address]
)
valid_code? = Code.is_same?(farm_transaction.code, expected_code)
end
end
# Ensure this transaction adds the reward token to the farm
valid_reward? = false
if valid_code? do
if reward_token == "UCO" do
valid_reward? = Map.get(transaction.uco_transfers, farm_genesis_address) != nil
else
transfers = Map.get(transaction.token_transfers, farm_genesis_address)
for transfer in transfers do
if transfer.token_address == reward_token do
valid_reward? = true
end
end
end
end
lp_token_exists? && valid_date? && valid_code? && valid_reward?
)
]
actions triggered_by: transaction, on: add_farm(lp_token, start_date, end_date, reward_token, farm_creation_address) do
farms = State.get("farms", [])
farm_genesis_address = Chain.get_genesis_address(farm_creation_address)
new_farm = [
lp_token_address: lp_token,
start_date: start_date,
end_date: end_date,
reward_token: reward_token,
address: farm_genesis_address
]
farms = List.prepend(farms, new_farm)
State.set("farms", farms)
end
condition triggered_by: transaction, on: update_code(new_code), as: [
previous_public_key: (
# Router code can only be updated from the master chain of the dex
# Transaction is not yet validated so we need to use previous address
# to get the genesis address
previous_address = Chain.get_previous_address()
Chain.get_genesis_address(previous_address) == 0x0000e46f8e90074ddf1dfc46385e07d826d35251f3a7b7ff65ad6f7e4b138aff7c10
),
code: Code.is_valid?(new_code)
]
actions triggered_by: transaction, on: update_code(new_code) do
Contract.set_type("contract")
Contract.set_code(new_code)
end
condition triggered_by: transaction, on: update_pools_code(), as: [
previous_public_key: (
# Pool code update can only be requested from the master chain of the dex
# Transaction is not yet validated so we need to use previous address
# to get the genesis address
previous_address = Chain.get_previous_address()
Chain.get_genesis_address(previous_address) == 0x0000e46f8e90074ddf1dfc46385e07d826d35251f3a7b7ff65ad6f7e4b138aff7c10
)
]
actions triggered_by: transaction, on: update_pools_code() do
pools = State.get("pools", Map.new())
if Map.size(pools) > 0 do
for pool_info in Map.values(pools) do
Contract.add_recipient address: pool_info.address, action: "update_code", args: []
end
Contract.set_type("transfer")
end
end
condition triggered_by: transaction, on: update_farms_code(), as: [
previous_public_key: (
# Pool code update can only be requested from the master chain of the dex
# Transaction is not yet validated so we need to use previous address
# to get the genesis address
previous_address = Chain.get_previous_address()
Chain.get_genesis_address(previous_address) == 0x0000e46f8e90074ddf1dfc46385e07d826d35251f3a7b7ff65ad6f7e4b138aff7c10
)
]
actions triggered_by: transaction, on: update_farms_code() do
farms = State.get("farms", [])
if List.size(farms) > 0 do
for farm in farms do
Contract.add_recipient address: farm.address, action: "update_code", args: []
end
Contract.set_type("transfer")
end
end
fun get_pool_id(token1_address, token2_address) do
if token1_address > token2_address do
temp = token1_address
token1_address = token2_address
token2_address = temp
end
"#{token1_address}/#{token2_address}"
end
fun valid_token?(token_address) do
valid? = false
if token_address == "UCO" do
valid? = true
else
tx = Chain.get_transaction(token_address)
# Transaction must have type token
# Token must be fungible
if tx != nil && tx.type == "token" do
token_definition = Json.parse(tx.content)
valid? = token_definition.type == "fungible"
end
end
valid?
end
export fun get_pool_addresses(token1_address, token2_address) do
token1_address = String.to_uppercase(token1_address)
token2_address = String.to_uppercase(token2_address)
if token1_address > token2_address do
temp = token1_address
token1_address = token2_address
token2_address = temp
end
pool_id = "#{token1_address}/#{token2_address}"
pools = State.get("pools", Map.new())
Map.get(pools, pool_id, nil)
end
export fun get_pool_list() do
pools = State.get("pools", Map.new())
list = []
for pool_id in Map.keys(pools) do
pool = Map.get(pools, pool_id)
pool = Map.set(pool, "tokens", pool_id)
list = List.prepend(list, pool)
end
list
end
export fun get_farm_list() do
State.get("farms", [])
end
Content (0 B)
{
"pools": {
"00003DF600E329199BF3EE8FBE2B8223413D70BCDD97E15089E6A74D94DE3F1173B4/0000908C7DD6B39760EF3A29CD4173A16DCD2183EC2AB5BCF851335DC162DE2BD060": {
"address": "000025C64E795E4B6A029256CB648D601851B97470EC4F54CBBFD301F02D356FDD05",
"lp_token_address": "0000E6A6DECE48C02F248EB8866FD08E83B9CE50AB5EEFB58F89BFC79E7492B3690B"
},
"00003DF600E329199BF3EE8FBE2B8223413D70BCDD97E15089E6A74D94DE3F1173B4/0000E06BFF011D495E21EA9D5266435BBF2B5E721464132E4D24C404F51B0AFA8699": {
"address": "0000E691507E13F81CD7EC50453A95F447B778277653213278F20C42F74EBFF9046E",
"lp_token_address": "000035ACC0A03D7FDCB940F5F6E4DC65384033A9731B6B57C68D82DEA45C8B4EE622"
},
"00003DF600E329199BF3EE8FBE2B8223413D70BCDD97E15089E6A74D94DE3F1173B4/UCO": {
"address": "0000818EF23676779DAE1C97072BB99A3E0DD1C31BAD3787422798DBE3F777F74A43",
"lp_token_address": "00006394EF24DFDC6FDFC3642FDC83827591A485704BB997221C0B9F313A468BDEAF"
},
"0000653684A3FC48B47AD2F0DB5793FD03748FB56B8868BEC0AE091CD3968106E481/UCO": {
"address": "0000469434BDBB816E178F0CC423AFB921802F18FFCD432BF5E8004BCE0270A65E55",
"lp_token_address": "0000d0d1e6c5703b599aa5aa3abf443f742d908644e6e500682870a23b187d515c90"
},
"0000887597E85A2DF06070466A25DEF55CBE2988A8EBEB5B6F3655F7444B4BBFE42A/UCO": {
"address": "00006D18313F839B585A4AC2730F58DC065D122F223C4E3A28962883F17D02514A26",
"lp_token_address": "0000774B49CAF598D83C1F32765B50D2DD4F3404E5357ABC126AE06E73AE66F061C3"
},
"0000E06BFF011D495E21EA9D5266435BBF2B5E721464132E4D24C404F51B0AFA8699/UCO": {
"address": "0000D5BC05EC984F531E27E74E2804AB1DF1DD856B821D37F87D5AD9FDE9F4440966",
"lp_token_address": "00004638E1D7397E8050826D1861194854F1105F568FCA616F99981507DAA5653EE7"
},
"0000E7367B119C45B5D92363E0E6C3E0067A6AD9E0B8C7CC7AB475AFFB010B24E380/UCO": {
"address": "0000F92743735B9D8E7CCA5617D37F93B5E4A6036DABF1CDE8DB77CD0633B0D8671C",
"lp_token_address": "000029C3AD030244EA5F0358D0F31D74E7DAE20DC9906ABED6C5775D5D73A1B2B4A6"
}
}
}
-
Secret shared with 1 key
Encoded secret
5ED26EF294BA2A9D849EA9033A0F78AE948B84021DE5E710A7A4C26E8C687753D31273CA135EFBF97D9D0392767C0A1A92E0D22E44FEF9FF3C9D987D
Authorized keys
- 00017877BCF4122095926A49489009649603AB129822A19EF9D573B8FD714911ED7F
Contract recipients (0)
Inputs (0)
Contract inputs (0)
Unspent outputs (1)
-
From 0000733E...F6A7At 2024-01-30 18:24:48 UTCAmount 0.00223864 UCO
Previous public key
0001E642EB1F9DFA00FBB02F3602A87D97C3B8354DA0D5019356AA69D88108DACC0C
Previous signature
AE0802036231A3139B7D882A3B9987D5A6B8178F6B07E201FCF79B38C6FAD9B6E3637A5EA6BB2620859D011B1D76A3040D50BB2097BF5B05BF6AA0D885CCA605
Origin signature
3046022100D04C1E9AB44E5F151832152F24D57340DBF2DA3C818EFF0781E96F277A13F52F022100B6439F950463DD1839107D2B84284362D2496ADE375CDD808CF2B25AEDE58B92
Proof of work
01020451684966573439C38DA99334546FBBDE4A6D96A50B4A4ECBB6572CDBED023F079607407E254421D1779525D11C60D55684F0B403B93B95823554E29D1E2CDB16
Proof of integrity
0086F4EC0C14C5EFA0F3304C0FC0ABD68CC9CE22ABE8C80DF20D768FE1BB293337
Coordinator signature
0FCBE84ECBDEE5A7FECD81F7A8E03190616FC8496FDBC9470FF451B7F1347D69A33D40B9080E232B311CE27CEF5CDF9F4C36706F30DBEA805E41B0EE7D1D080D
Validator #1 public key
0001500FBE298B79FFBDD5CCA1798F30FD88A53D26EC39DE5DDE1F4137B032A4BC34
Validator #1 signature
AE8E135F188D3D7257F146F9A8F348C2B0BB265E413FD274475F5933CBC39ED88FA29133C10FD9D568BDBC06A56CBF7674A0272E1F2BDF03FD4767F71E1DAA03
Validator #2 public key
000151C124A6211CD402FD1CFE560C5DB51ED0CBEF44B09B21A41206028E7E5942BF
Validator #2 signature
4265357F226B49E9A2FA3B3E61A72CB40BDA697F5D756E47BC7F5E4CB3C4712DB165B02786ED2320D47FF85121B04FBCDFB62DD3BFE3E5B76FCD65D6D98BB409