Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add throw errors msg for AE contracts #37

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 121 additions & 95 deletions archethic/contracts/factory.exs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
@version 1

# condition inherit: [
# # Add condition inherit to allow upgrade of this contract
# ]

export fun get_protocol_fee() do
0.3
end
Expand Down Expand Up @@ -87,47 +83,43 @@ export fun get_chargeable_htlc(end_time, user_address, pool_address, secret_hash
"""
@version 1

condition triggered_by: transaction, on: provision(_evm_contract, _endpoints, _signature, _evm_pool), as: [
previous_public_key: (
# 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) == 0x#{pool_address}
)
]
condition triggered_by: transaction, on: provision(_evm_contract, _endpoints, _signature, _evm_pool) do
# Transaction is not yet validated so we need to use previous address to get the genesis address
previous_address = Chain.get_previous_address(transaction)
genesis_address = Chain.get_genesis_address(previous_address)
if genesis_address != 0x#{pool_address} do
throw message: "Transaction's chain unauthorized", code: 403
end

true
end

actions triggered_by: transaction, on: provision(evm_contract, endpoints, signature, evm_pool) do
endpoints = Json.to_string(endpoints)
Contract.set_code \"""
@version 1

condition triggered_by: transaction, on: refund(), as: [
content: (
valid? = false

abi_data = Evm.abi_encode("status()")
tx = [to: "\#{evm_contract}", data: "0x\\\#{abi_data}"]
request = [jsonrpc: "2.0", id: "1", method: "eth_call", params: [tx, "latest"]]

headers = ["Content-Type": "application/json"]
body = Json.to_string(request)

evm_responses = query_evm_apis(\#{endpoints}, "POST", headers, body)
for res in evm_responses do
if !valid? && res.status == 200 && Json.is_valid?(res.body) do
response = Json.parse(res.body)
result = Map.get(response, "result")
if result != nil do
decoded_abi = Evm.abi_decode("(uint)", result)
# Refund status is 2
valid? = List.at(decoded_abi, 0) == 2
end
end
end
condition triggered_by: transaction, on: refund() do
abi_data = Evm.abi_encode("status()")
tx = [to: "\#{evm_contract}", data: "0x\\\#{abi_data}"]
request = [jsonrpc: "2.0", id: "1", method: "eth_call", params: [tx, "latest"]]

valid?
)
]
evm_response = query_evm_apis(\#{endpoints}, body)
result = Map.get(evm_response, "result")
if result == nil do
throw message: "Invalid EVM RPC response", data: evm_response, code: 500
end

decoded_abi = Evm.abi_decode("(uint)", result)

# Refund status is 2
htlc_status = List.at(decoded_abi, 0)
if htlc_status != 2 do
throw message: "Cannot refund the HTLC before EVM", data: [evm_htlc_status: htlc_status], code: 405
end

true
end

actions triggered_by: transaction, on: refund() do
Contract.set_type "transfer"
Expand All @@ -147,35 +139,31 @@ export fun get_chargeable_htlc(end_time, user_address, pool_address, secret_hash
\\\"""
end

condition triggered_by: transaction, on: reveal_secret(secret), as: [
content: Crypto.hash(String.to_hex(secret)) == 0x#{secret_hash},
address: (
valid? = false

abi_data = Evm.abi_encode("status()")
tx = [to: "\#{evm_contract}", data: "0x\\\#{abi_data}"]
request = [jsonrpc: "2.0", id: "1", method: "eth_call", params: [tx, "latest"]]

headers = ["Content-Type": "application/json"]
body = Json.to_string(request)

responses = query_evm_apis(\#{endpoints}, "POST", headers, body)
for res in responses do
if !valid? && res.status == 200 && Json.is_valid?(res.body) do
response = Json.parse(res.body)
result = Map.get(response, "result")

if result != nil do
decoded_abi = Evm.abi_decode("(uint)", result)
# Withdrawn status is 1
valid? = List.at(decoded_abi, 0) == 1
end
end
end
condition triggered_by: transaction, on: reveal_secret(secret) do
if Crypto.hash(String.to_hex(secret)) != 0x#{secret_hash} do
throw message: "Invalid secret", code: 400
end

valid?
)
]
abi_data = Evm.abi_encode("status()")
tx = [to: "\#{evm_contract}", data: "0x\\\#{abi_data}"]
request = [jsonrpc: "2.0", id: "1", method: "eth_call", params: [tx, "latest"]]

response = query_evm_apis(\#{endpoints}, request)
result = Map.get(response, "result")

if result == nil do
throw message: "Invalid EVM RPC response", data: response, code: 500
end

decoded_abi = Evm.abi_decode("(uint)", result)
status = List.at(decoded_abi, 0)
# Withdrawn status is 1
if status != 1 do
throw message: "Cannot withdraw the HTLC before EVM", data: [evm_htlc_status: htlc_status], code: 405
end

true
end

actions triggered_by: transaction, on: reveal_secret(secret) do
Contract.set_type "transfer"
Expand All @@ -194,13 +182,34 @@ export fun get_chargeable_htlc(end_time, user_address, pool_address, secret_hash
end
\\\"""
end
fun query_evm_apis(endpoints, method, headers, body) do

fun query_evm_apis(endpoints, body) do
requests = []
for endpoint in endpoints do
requests = List.append(requests, url: endpoint, method: method, headers: headers, body: body)
requests = List.append(requests, url: endpoint, method: "POST", headers: ["Content-Type": "application/json"], body: Json.to_string(body))
end
Http.request_many(requests, false)

responses = Http.request_many(requests, false)

valid_http_request? = false
valid_response = nil
errorDetails = []
for res in responses do
if !valid_http_request? do
if res.status == 200 && Json.is_valid?(res.body) do
valid_response = Json.parse(res.body)
valid_http_request? = true
else
errorDetails = List.append(errorDetails, [status: res.status, body: res.body])
end
end
end

if !valid_http_request? do
throw message: "Cannot fetch EVM RPC endpoints", code: 500, data: errorDetails
end

valid_response
end

export fun get_provision_signature() do
Expand Down Expand Up @@ -282,26 +291,35 @@ export fun get_signed_htlc(user_address, pool_address, token, amount) do
"""
@version 1

condition triggered_by: transaction, on: set_secret_hash(_secret_hash, _secret_hash_signature, _end_time, _evm_pool), as: [
previous_public_key: (
# 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) == 0x#{pool_address}
)
]
condition triggered_by: transaction, on: set_secret_hash(_secret_hash, _secret_hash_signature, _end_time, _evm_pool) do
# Transaction is not yet validated so we need to use previous address to get the genesis address
previous_address = Chain.get_previous_address(transaction)
genesis_address = Chain.get_genesis_address(previous_address)
if genesis_address != 0x#{pool_address} do
throw message: "Transaction's chain unauthorized", code: 403
end

true
end

actions triggered_by: transaction, on: set_secret_hash(secret_hash, secret_hash_signature, end_time, evm_pool) do
Contract.set_code \"""
@version 1

condition triggered_by: transaction, on: refund(secret, secret_signature), as: [
previous_public_key: (
previous_address = Chain.get_previous_address()
Chain.get_genesis_address(previous_address) == 0x#{pool_address}
),
timestamp: timestamp >= \#{end_time}
]
condition triggered_by: transaction, on: refund(secret, secret_signature) do
if transaction.timestamp < end_time do
throw message: "Refund cannot be done before the lock time", code: 405
end

# Transaction is not yet validated so we need to use previous address to get the genesis address
previous_address = Chain.get_previous_address(transaction)
genesis_address = Chain.get_genesis_address(previous_address)
if genesis_address != 0x#{pool_address} do
samuelmanzanera marked this conversation as resolved.
Show resolved Hide resolved
throw message: "Transaction's chain unauthorized", code: 403
end

true
end

actions triggered_by: transaction, on: refund(secret, secret_signature) do
Contract.set_type "transfer"
Expand Down Expand Up @@ -332,16 +350,24 @@ export fun get_signed_htlc(user_address, pool_address, token, amount) do
\\\"""
end

condition triggered_by: transaction, on: reveal_secret(secret, secret_signature, _evm_contract), as: [
previous_public_key: (
# 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) == 0x#{pool_address}
),
timestamp: transaction.timestamp < \#{end_time},
content: Crypto.hash(String.to_hex(secret)) == 0x\#{secret_hash}
]
condition triggered_by: transaction, on: reveal_secret(secret, secret_signature, _evm_contract) do
if transaction.timestamp >= \#{end_time} do
throw message: "Withdraw cannot be after after the end of the locktime", code: 405
end

if Crypto.hash(String.to_hex(secret)) != 0x\#{secret_hash} do
throw message: "Invalid secret", code: 400
end

# Transaction is not yet validated so we need to use previous address to get the genesis address
previous_address = Chain.get_previous_address(transaction)
genesis_address = Chain.get_genesis_address(previous_address)
if genesis_address != 0x#{pool_address} do
throw message: "Transaction's chain unauthorized", code: 403
end

true
end

actions triggered_by: transaction, on: reveal_secret(secret, secret_signature, evm_contract) do
Contract.set_type "transfer"
Expand Down
Loading
Loading