Module Name | Bridge | Module Reference | f184471d9e |
Verification Status | Verified |
Deployed in block | 20,235,819 |
Deployed in tx | 2ae4 |
Age | 149 days |
Sender | 98383 |
Methods | 23 |
Instances | 0 |
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
None
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"migrate": {
"Enum": [
{
"None": []
},
{
"Some": [
[
"<String>",
"<String with lowercase hex>"
]
]
}
]
},
"module": "<String of size 64 containing lowercase hex characters.>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
None
{
"deadline": "<UInt64>",
"nonce": "<UInt64>",
"payload": {
"amount": "<UInt128>",
"destination_address": "<String>",
"destination_chain": "<String>",
"gas_commission": "<UInt128>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
},
"transaction_id": "<UInt64>"
},
"signature": "<String>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"amount": "<UInt128>",
"recipient": "<AccountAddress>",
"source_address": "<String>",
"source_chain": "<String>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
},
"transaction_id": "<UInt64>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"deadline": "<UInt64>",
"nonce": "<UInt64>",
"payload": {
"amount": "<UInt128>",
"destination_address": "<String>",
"destination_chain": "<String>",
"gas_commission": "<UInt128>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
},
"transaction_id": "<UInt64>"
},
"signature": "<String>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"deadline": "<UInt64>",
"nonce": "<UInt64>",
"payload": {
"amount": "<UInt128>",
"destination_address": "<String>",
"destination_chain": "<String>",
"gas_commission": "<UInt128>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
},
"transaction_id": "<UInt64>"
},
"signature": "<String>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"amount": "<UInt128>",
"recipient": "<AccountAddress>",
"source_address": "<String>",
"source_chain": "<String>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
},
"transaction_id": "<UInt64>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"amount": "<UInt128>",
"recipient": "<AccountAddress>",
"source_address": "<String>",
"source_chain": "<String>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
},
"transaction_id": "<UInt64>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"amount": "<UInt128>",
"recipient": "<AccountAddress>",
"token_contract": {
"index": "<UInt64>",
"subindex": "<UInt64>"
}
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"amount": "<Amount in microCCD>",
"recipient": "<AccountAddress>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
"<String>"
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
"<AccountAddress>"
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
"<UInt64>"
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
{
"paused": "<Bool>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
[]
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<Bool>"
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<UInt64>"
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<String>"
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<AccountAddress>"
{
"index": "<UInt64>",
"subindex": "<UInt64>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<UInt128>"
{
"index": "<UInt64>",
"subindex": "<UInt64>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<UInt128>"
[]
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<UInt128>"
{
"amount": "<UInt128>",
"gas_commission": "<UInt128>"
}
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<UInt128>"
"<AccountAddress>"
{
"Enum": [
{
"ParseParams": []
},
{
"LogFull": []
},
{
"LogMalformed": []
},
{
"NotOwner": []
},
{
"UnexpectedTransferAmount": []
},
{
"ExpiredSignature": []
},
{
"AlreadyUsedSignature": []
},
{
"InvalidCommissionPercent": []
},
{
"AmountExceedCommissionPool": []
},
{
"AmountExceedBridgePool": []
},
{
"InvalidSignature": []
},
{
"SignerIsNotEstablished": []
},
{
"CommissionBiggerThanTransferredAmount": []
},
{
"CommissionOverflow": []
},
{
"AlreadySmashed": []
},
{
"TransferError": []
},
{
"InvalidCommissionCollector": []
},
{
"RemoteAmountTooLarge": []
},
{
"RemoteMissingAccount": []
},
{
"RemoteMissingContract": []
},
{
"RemoteMissingEntrypoint": []
},
{
"RemoteMessageFailed": []
},
{
"RemoteReject": {
"reason": "<Int32>"
}
},
{
"RemoteTrap": []
},
{
"RemoteUnexpectedResponse": []
},
{
"FailedUpgradeMissingModule": []
},
{
"FailedUpgradeMissingContract": []
},
{
"FailedUpgradeUnsupportedModuleVersion": []
},
{
"ContractPaused": []
}
]
}
"<UInt64>"
Verification performed at: | Verification pending |
Build Image Used: | docker.io/concordium/verifiable-sc:1.75.0 |
Build Command Used: | cargo --locked build --target wasm32-unknown-unknown --release --target-dir /b/t |
Archive Hash: | 6241e0626537a061f5e40286f6f3d4299e8a55ed6ebb238510220ea84d432df8 |
Link to Source Code: | Source Code |
Explanation: | Source and module match. |
// Pulling in everything from the smart contract standard library.
use concordium_cis2::*;
use concordium_std::*;
use token_params::*;
mod error;
pub mod token_params;
pub use error::{Error, Result};
pub type Nonce = u64;
pub type Deadline = u64;
pub type Balance = u128;
pub type ContractTokenId = TokenIdUnit;
pub type ContractTokenAmount = TokenAmountU128;
pub type ContractBalanceOfQueryParams = BalanceOfQueryParams<ContractTokenId>;
pub type ContractBalanceOfQueryResponse = BalanceOfQueryResponse<ContractTokenAmount>;
const BALANCE_OF_ENTRYPOINT: EntrypointName = EntrypointName::new_unchecked("balanceOf");
const TRANSFER_ENTRYPOINT: EntrypointName = EntrypointName::new_unchecked("transfer");
const BURN_ENTRYPOINT: EntrypointName = EntrypointName::new_unchecked("burn");
const MINT_ENTRYPOINT: EntrypointName = EntrypointName::new_unchecked("mint");
pub const DEFAULT_STABLE_COMMISSION_PERCENT: u16 = 1000;
pub const MAX_STABLE_COMMISSION_PERCENT: u16 = 5000;
pub const TOKEN_ID_WCCD: ContractTokenId = TokenIdUnit();
/// Describes message which gets actually signed
#[derive(Serial)]
pub struct SigningPayload<T: Serial> {
pub self_address: ContractAddress,
pub sender: AccountAddress,
pub nonce: Nonce,
pub deadline: Deadline,
pub message: T,
}
/// Signed method parameters,
/// include signature and some additional info along with actual payload
#[derive(Serialize, SchemaType)]
pub struct Signed<T> {
pub signature: String,
pub nonce: Nonce,
pub deadline: Deadline,
pub payload: T,
}
fn get_self_balance<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
token_contract: &ContractAddress,
) -> Result<Balance> {
let balanceof_params: ContractBalanceOfQueryParams = ContractBalanceOfQueryParams {
queries: vec![BalanceOfQuery {
token_id: TOKEN_ID_WCCD,
address: Address::Contract(ctx.self_address()),
}],
};
let byte_params = to_bytes(&balanceof_params);
let data = host
.invoke_contract_raw_read_only(
token_contract,
Parameter::new_unchecked(&byte_params),
BALANCE_OF_ENTRYPOINT,
Amount::zero(),
)
.map_err(Error::from)?;
let balances: ContractBalanceOfQueryResponse = data
.ok_or(Error::RemoteUnexpectedResponse)?
.get()
.map_err(|_| Error::RemoteUnexpectedResponse)?;
Ok(balances.0.get(0).ok_or(Error::RemoteUnexpectedResponse)?.0)
}
fn signed_params<S: HasStateApi, T: Serialize>(
ctx: &impl HasReceiveContext,
crypto: &impl HasCryptoPrimitives,
state: &mut State<S>,
) -> Result<(T, Nonce)> {
let Signed {
signature,
nonce,
deadline,
payload,
} = ctx.parameter_cursor().get()?;
ensure!(
Timestamp::from_timestamp_millis(deadline) > ctx.metadata().slot_time(),
Error::ExpiredSignature
);
let self_address = ctx.self_address();
let sender = ctx.invoker();
{
let mut nonce_entry = state.user_nonces.entry(sender).or_default();
ensure!(*nonce_entry == nonce, Error::AlreadyUsedSignature);
// Wrapping 2^64 is long enough, even with one request per second
*nonce_entry = nonce_entry.wrapping_add(1);
}
let signed_message = SigningPayload {
self_address,
sender,
nonce,
deadline,
message: &payload,
};
let message_bytes = to_bytes(&signed_message);
let signature: SignatureEd25519 = signature.parse().map_err(|_| Error::InvalidSignature)?;
let signer_key = state.default_signer.ok_or(Error::SignerIsNotEstablished)?;
ensure!(
// `CryptoPrimitives::verify_ed25519_signature` uses `ed25519_zebra`.
// More specifically, it uses its `VerificationKey::verify` which in turn
// performs hashing on its own, so no need to explicitly hash it on our side
crypto.verify_ed25519_signature(signer_key, signature, &message_bytes),
Error::InvalidSignature
);
Ok((payload, nonce))
}
fn transfer_amount_to_contract<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
token_contract: ContractAddress,
amount: u128,
) -> Result<()> {
let transfer_params = Transfer {
token_id: TOKEN_ID_WCCD,
amount: ContractTokenAmount::from(amount),
from: Address::Account(ctx.invoker()),
to: Receiver::from_contract(
ctx.self_address(),
OwnedEntrypointName::new_unchecked("onReceiveTokens".to_string()),
),
data: AdditionalData::empty(),
};
type TransferParameter = TransferParams<ContractTokenId, ContractTokenAmount>;
let parameter: TransferParameter = TransferParams::from(vec![transfer_params]);
host.invoke_contract(
&token_contract,
¶meter,
TRANSFER_ENTRYPOINT,
Amount::zero(),
)
.map(|_| ())
.map_err(Error::from)
}
fn increase_token_commission<S: HasStateApi>(
state: &mut State<S>,
token_contract: ContractAddress,
total_commission: u128,
) -> Result<()> {
let mut commission_by_token = state.commission_by_token.entry(token_contract).or_insert(0);
*commission_by_token = commission_by_token
.checked_add(total_commission)
.ok_or(Error::CommissionOverflow)?;
Ok(())
}
#[derive(Debug, Serial, DeserialWithState)]
#[concordium(state_parameter = "S")]
pub struct State<S: HasStateApi> {
pub commission_by_coin: u128,
pub commission_collector: AccountAddress,
pub default_percent: u16,
pub default_signer: Option<PublicKeyEd25519>,
pub user_nonces: StateMap<AccountAddress, Nonce, S>,
pub commission_by_token: StateMap<ContractAddress, u128, S>,
// pub paused: bool, // TODO
}
impl<S: HasStateApi> State<S> {
fn get_total_commission(&self, amount: Balance, gas_commission: Balance) -> Result<Balance> {
amount
.checked_mul(Balance::from(self.default_percent))
.ok_or(Error::CommissionOverflow)?
.checked_div(10_000)
.ok_or(Error::CommissionOverflow)?
.checked_add(gas_commission)
.ok_or(Error::CommissionOverflow)
}
fn ensure_unpaused(&self) -> Result<()> {
// ensure!(!self.paused, Error::ContractPaused); // TODO
ensure!(true, Error::ContractPaused); // TODO
Ok(())
}
}
#[derive(Serialize, SchemaType)]
pub struct FundsInPayload {
pub token_contract: ContractAddress,
pub amount: u128,
pub gas_commission: u128,
pub transaction_id: u64,
pub destination_chain: String,
pub destination_address: String,
}
pub type FundsInParams = Signed<FundsInPayload>;
#[derive(Serialize, SchemaType)]
pub struct FundsOutParams {
pub token_contract: ContractAddress,
pub amount: u128,
pub transaction_id: u64,
pub source_chain: String,
pub source_address: String,
pub recipient: AccountAddress,
}
#[derive(Serialize, SchemaType)]
pub struct FundsOutNativeParams {
pub amount: Amount,
pub transaction_id: u64,
pub source_chain: String,
pub source_address: String,
pub recipient: AccountAddress,
}
#[derive(Serialize, SchemaType)]
pub struct GetTotalCommissionParams {
pub amount: u128,
pub gas_commission: u128,
}
#[derive(Serialize, SchemaType)]
pub struct WithdrawCommissionParams {
pub token_contract: ContractAddress,
pub amount: u128,
pub recipient: AccountAddress,
}
#[derive(Serialize, SchemaType)]
pub struct WithdrawCoinCommissionParams {
pub amount: Amount,
pub recipient: AccountAddress,
}
#[derive(Serialize, SchemaType)]
pub struct UpgradeParams {
pub module: ModuleReference,
pub migrate: Option<(OwnedEntrypointName, OwnedParameter)>,
}
#[derive(Serialize, SchemaType, PartialEq, Eq, Debug)]
#[repr(transparent)]
pub struct SetPausedParams {
/// Contract is paused if `paused = true` and unpaused if `paused = false`.
pub paused: bool,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct FundsInEvent {
pub token_contract: ContractAddress,
pub destination_chain: String,
pub destination_address: String,
pub amount: u128,
pub gas_commission: u128,
pub stable_commission_percent: u16,
pub nonce: Nonce,
pub transaction_id: u64,
pub sender: Address,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct FundsInNativeEvent {
pub contract_coin_balance: Amount,
pub coin_amount: Amount,
pub destination_chain: String,
pub destination_address: String,
pub gas_commission: u128,
pub stable_commission_percent: u16,
pub nonce: Nonce,
pub transaction_id: u64,
pub sender: Address,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct FundsInBurnEvent {
pub token_contract: ContractAddress,
pub destination_chain: String,
pub destination_address: String,
pub amount: u128,
pub gas_commission: u128,
pub stable_commission_percent: u16,
pub nonce: Nonce,
pub transaction_id: u64,
pub sender: Address,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct FundsOutEvent {
pub token_contract: ContractAddress,
pub source_chain: String,
pub source_address: String,
pub amount: u128,
pub transaction_id: u64,
pub recipient: AccountAddress,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct FundsOutNativeEvent {
pub source_chain: String,
pub source_address: String,
pub amount: Amount,
pub transaction_id: u64,
pub recipient: AccountAddress,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct FundsOutMintEvent {
pub token_contract: ContractAddress,
pub source_chain: String,
pub source_address: String,
pub amount: u128,
pub transaction_id: u64,
pub recipient: AccountAddress,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct TransferOutEvent {
pub token_contract: ContractAddress,
pub total_sum_for_transfer: u128,
pub nonce: Nonce,
pub recipient: AccountAddress,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct WithdrawCommissionEvent {
pub token_contract: ContractAddress,
pub amount: u128,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct WithdrawCoinCommissionEvent {
pub amount: Amount,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct SetSignerEvent {
pub default_signer: String,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct SetCommissionCollectorEvent {
pub commission_collector: AccountAddress,
}
#[derive(Debug, Serialize, SchemaType, PartialEq, Eq)]
pub struct SetStableCommissionPercentEvent {
pub stable_commission_percent: u16,
}
#[derive(Serialize, SchemaType, PartialEq, Eq, Debug)]
#[repr(transparent)]
#[concordium(transparent)]
pub struct SetPausedEvent {
pub paused: bool,
}
#[derive(Debug, Serialize, SchemaType)]
enum BridgeEvent {
FundsIn(FundsInEvent),
FundsInBurn(FundsInBurnEvent),
FundsOut(FundsOutEvent),
FundsOutMint(FundsOutMintEvent),
WithdrawCommission(WithdrawCommissionEvent),
WithdrawCoinCommissionEvent(WithdrawCoinCommissionEvent),
FundsInNative(FundsInNativeEvent),
FundsOutNative(FundsOutNativeEvent),
SetSigner(SetSignerEvent),
SetCommissionCollector(SetCommissionCollectorEvent),
SetStableCommissionPercent(SetStableCommissionPercentEvent),
SetPaused(SetPausedEvent),
}
/// Serves as stub endpoint when contract receives tokens from CIS2-compliant token contract
#[receive(
contract = "Bridge",
name = "onReceiveTokens",
parameter = "()",
return_value = "()",
error = "Error"
)]
fn on_receive_tokens<S: HasStateApi>(
_: &impl HasReceiveContext,
_: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<()> {
Ok(())
}
/// Inits new instance of bridge contract
#[init(contract = "Bridge", parameter = "()", error = "Error")]
fn bridge_init<S: HasStateApi>(
_: &impl HasInitContext,
state_builder: &mut StateBuilder<S>,
) -> Result<State<S>> {
let state = State {
commission_collector: AccountAddress([0u8; 32]),
default_percent: DEFAULT_STABLE_COMMISSION_PERCENT,
default_signer: None,
user_nonces: state_builder.new_map(),
commission_by_coin: 0,
commission_by_token: state_builder.new_map(),
// paused: false, // TODO
};
Ok(state)
}
#[receive(
contract = "Bridge",
name = "upgrade",
parameter = "UpgradeParams",
error = "Error",
low_level
)]
fn contract_upgrade(ctx: &ReceiveContext, host: &mut LowLevelHost) -> Result<()> {
let owner = ctx.owner();
let sender: Address = ctx.sender();
ensure!(sender.matches_account(&owner), Error::NotOwner);
let params: UpgradeParams = ctx.parameter_cursor().get()?;
host.upgrade(params.module)?;
if let Some((func, parameters)) = params.migrate {
host.invoke_contract_raw(
&ctx.self_address(),
parameters.as_parameter(),
func.as_entrypoint_name(),
Amount::zero(),
)?;
}
Ok(())
}
#[receive(
contract = "Bridge",
name = "funds_in_native",
parameter = "FundsInParams",
return_value = "()",
error = "Error",
crypto_primitives,
mutable,
enable_logger,
payable
)]
fn funds_in_native<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
amount: Amount,
logger: &mut impl HasLogger,
crypto: &impl HasCryptoPrimitives,
) -> Result<()> {
let state = host.state_mut();
state.ensure_unpaused()?;
let balance = host.self_balance();
let state = host.state_mut();
let (params, nonce): (FundsInPayload, _) = signed_params(ctx, crypto, state)?;
let sender: Address = ctx.sender();
let amount_value = amount.micro_ccd();
let total_commission =
state.get_total_commission(amount_value as u128, params.gas_commission)?;
state.commission_by_coin = state
.commission_by_coin
.checked_add(total_commission)
.ok_or(Error::CommissionOverflow)?;
logger.log(&BridgeEvent::FundsInNative(FundsInNativeEvent {
contract_coin_balance: balance,
coin_amount: amount,
destination_chain: params.destination_chain,
destination_address: params.destination_address,
gas_commission: params.gas_commission,
stable_commission_percent: state.default_percent,
nonce,
transaction_id: params.transaction_id,
sender,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "funds_out_native",
parameter = "FundsOutParams",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn funds_out_native<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
let params: FundsOutNativeParams = ctx.parameter_cursor().get()?;
let amount = params.amount;
let self_balance = host.self_balance().micro_ccd();
let state = host.state_mut();
let commission_by_coin = state.commission_by_coin;
ensure!(sender.matches_account(&owner), Error::NotOwner);
let allowed_balance = Balance::from(self_balance)
.checked_sub(commission_by_coin)
.ok_or(Error::CommissionBiggerThanTransferredAmount)?;
ensure!(
allowed_balance >= amount.micro_ccd() as u128,
Error::AmountExceedBridgePool
);
host.invoke_transfer(¶ms.recipient, params.amount)
.map_err(Error::from)?;
logger.log(&BridgeEvent::FundsOutNative(FundsOutNativeEvent {
source_chain: params.source_chain,
source_address: params.source_address,
amount: params.amount,
transaction_id: params.transaction_id,
recipient: params.recipient,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "funds_in",
parameter = "FundsInParams",
return_value = "()",
error = "Error",
crypto_primitives,
mutable,
enable_logger
)]
fn funds_in<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
crypto: &impl HasCryptoPrimitives,
) -> Result<()> {
let state = host.state_mut();
state.ensure_unpaused()?;
let (params, nonce): (FundsInPayload, _) = signed_params(ctx, crypto, state)?;
let default_percent = state.default_percent;
let sender: Address = ctx.sender();
let total_commission = state.get_total_commission(params.amount, params.gas_commission)?;
increase_token_commission(state, params.token_contract, total_commission)?;
//
// Interact with token contract
//
transfer_amount_to_contract(ctx, host, params.token_contract, params.amount)?;
logger.log(&BridgeEvent::FundsIn(FundsInEvent {
token_contract: params.token_contract,
destination_chain: params.destination_chain,
destination_address: params.destination_address,
amount: params.amount,
gas_commission: params.gas_commission,
stable_commission_percent: default_percent,
nonce,
transaction_id: params.transaction_id,
sender,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "funds_in_burn",
parameter = "FundsInParams",
return_value = "()",
error = "Error",
crypto_primitives,
mutable,
enable_logger
)]
fn funds_in_burn<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
crypto: &impl HasCryptoPrimitives,
) -> Result<()> {
let state = host.state_mut();
state.ensure_unpaused()?;
let (params, nonce): (FundsInPayload, _) = signed_params(ctx, crypto, state)?;
let default_percent = state.default_percent;
let sender: Address = ctx.sender();
let total_commission = state.get_total_commission(params.amount, params.gas_commission)?;
increase_token_commission(state, params.token_contract, total_commission)?;
//
// Interact with token contract
//
transfer_amount_to_contract(ctx, host, params.token_contract, total_commission)?;
let burn_params = BurnParams {
token_id: TOKEN_ID_WCCD,
amount: ContractTokenAmount::from(
params
.amount
.checked_sub(total_commission)
.ok_or(Error::CommissionBiggerThanTransferredAmount)?,
),
recipient: Address::Account(ctx.invoker()),
};
host.invoke_contract(
¶ms.token_contract,
&burn_params,
BURN_ENTRYPOINT,
Amount::zero(),
)
.map_err(Error::from)?;
logger.log(&BridgeEvent::FundsInBurn(FundsInBurnEvent {
token_contract: params.token_contract,
destination_chain: params.destination_chain,
destination_address: params.destination_address,
amount: params.amount,
gas_commission: params.gas_commission,
stable_commission_percent: default_percent,
nonce,
transaction_id: params.transaction_id,
sender,
}))?;
Ok(())
}
/// Withdraw tokens from Bridge contract onto user wallet
#[receive(
contract = "Bridge",
name = "funds_out",
parameter = "FundsOutParams",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn funds_out<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
let params: FundsOutParams = ctx.parameter_cursor().get()?;
let amount = params.amount;
let commission_by_token = host
.state()
.commission_by_token
.get(¶ms.token_contract)
.map(|state_ref| *state_ref)
.unwrap_or(0);
ensure!(sender.matches_account(&owner), Error::NotOwner);
let transfer_params = Transfer {
token_id: TOKEN_ID_WCCD,
amount: ContractTokenAmount::from(amount),
from: Address::Contract(ctx.self_address()),
to: Receiver::from_account(params.recipient),
data: AdditionalData::empty(),
};
type TransferParameter = TransferParams<ContractTokenId, ContractTokenAmount>;
let parameter: TransferParameter = TransferParams::from(vec![transfer_params]);
let self_balance = get_self_balance(ctx, host, ¶ms.token_contract)?;
let allowed_balance = self_balance
.checked_sub(commission_by_token)
.ok_or(Error::CommissionBiggerThanTransferredAmount)?;
ensure!(allowed_balance >= amount, Error::AmountExceedBridgePool);
host.invoke_contract(
¶ms.token_contract,
¶meter,
TRANSFER_ENTRYPOINT,
Amount::zero(),
)
.map_err(Error::from)?;
logger.log(&BridgeEvent::FundsOut(FundsOutEvent {
token_contract: params.token_contract,
source_chain: params.source_chain,
source_address: params.source_address,
amount: params.amount,
transaction_id: params.transaction_id,
recipient: params.recipient,
}))?;
Ok(())
}
/// Withdraw tokens from Bridge contract onto user wallet
#[receive(
contract = "Bridge",
name = "funds_out_mint",
parameter = "FundsOutParams",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn funds_out_mint<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
ensure!(sender.matches_account(&owner), Error::NotOwner);
let params: FundsOutParams = ctx.parameter_cursor().get()?;
let amount = params.amount;
let mint_params = MintParams {
token_id: TOKEN_ID_WCCD,
amount: ContractTokenAmount::from(amount),
recipient: Address::Account(params.recipient),
};
host.invoke_contract(
¶ms.token_contract,
&mint_params,
MINT_ENTRYPOINT,
Amount::zero(),
)
.map_err(Error::from)?;
logger.log(&BridgeEvent::FundsOutMint(FundsOutMintEvent {
token_contract: params.token_contract,
source_chain: params.source_chain,
source_address: params.source_address,
amount: params.amount,
transaction_id: params.transaction_id,
recipient: params.recipient,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "withdraw_commission",
parameter = "WithdrawCommissionParams",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn withdraw_commission<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let state = host.state_mut();
let commission_collector = state.commission_collector;
let sender = ctx.sender();
let params: WithdrawCommissionParams = ctx.parameter_cursor().get()?;
ensure!(
sender.matches_account(&commission_collector),
Error::InvalidCommissionCollector
);
let amount = params.amount;
{
let mut stored_commission = state
.commission_by_token
.entry(params.token_contract)
.or_default();
*stored_commission = stored_commission
.checked_sub(amount)
.ok_or(Error::AmountExceedCommissionPool)?;
}
let transfer_params = Transfer {
token_id: TOKEN_ID_WCCD,
amount: ContractTokenAmount::from(amount),
from: Address::Contract(ctx.self_address()),
to: Receiver::from_account(params.recipient),
data: AdditionalData::empty(),
};
type TransferParameter = TransferParams<ContractTokenId, ContractTokenAmount>;
let parameter: TransferParameter = TransferParams::from(vec![transfer_params]);
host.invoke_contract(
¶ms.token_contract,
¶meter,
TRANSFER_ENTRYPOINT,
Amount::zero(),
)
.map_err(Error::from)?;
logger.log(&BridgeEvent::WithdrawCommission(WithdrawCommissionEvent {
token_contract: params.token_contract,
amount,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "withdraw_coin_commission",
parameter = "WithdrawCoinCommissionParams",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn withdraw_coin_commission<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let state = host.state_mut();
let commission_collector = state.commission_collector;
let sender = ctx.sender();
let params: WithdrawCoinCommissionParams = ctx.parameter_cursor().get()?;
ensure!(
sender.matches_account(&commission_collector),
Error::InvalidCommissionCollector
);
let amount = params.amount;
state.commission_by_coin = state
.commission_by_coin
.checked_sub(amount.micro_ccd() as u128)
.ok_or(Error::AmountExceedCommissionPool)?;
host.invoke_transfer(¶ms.recipient, amount)
.map_err(Error::from)?;
logger.log(&BridgeEvent::WithdrawCoinCommissionEvent(
WithdrawCoinCommissionEvent { amount },
))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "set_signer",
parameter = "String",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn set_signer<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
let signer: String = ctx.parameter_cursor().get()?;
ensure!(sender.matches_account(&owner), Error::NotOwner);
host.state_mut().default_signer = Some(signer.parse()?);
logger.log(&BridgeEvent::SetSigner(SetSignerEvent {
default_signer: signer,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "set_commission_collector",
parameter = "AccountAddress",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn set_commission_collector<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
ensure!(sender.matches_account(&owner), Error::NotOwner);
let commission_collector: AccountAddress = ctx.parameter_cursor().get()?;
host.state_mut().commission_collector = commission_collector;
logger.log(&BridgeEvent::SetCommissionCollector(
SetCommissionCollectorEvent {
commission_collector,
},
))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "set_stable_commission_percent",
parameter = "u64",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn set_stable_commission_percent<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &mut impl HasHost<State<S>, StateApiType = S>,
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
ensure!(sender.matches_account(&owner), Error::NotOwner);
let stable_commission_percent: u16 = ctx.parameter_cursor().get()?;
ensure!(
stable_commission_percent <= MAX_STABLE_COMMISSION_PERCENT,
Error::InvalidCommissionPercent
);
host.state_mut().default_percent = stable_commission_percent;
logger.log(&BridgeEvent::SetStableCommissionPercent(
SetStableCommissionPercentEvent {
stable_commission_percent,
},
))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "set_paused",
parameter = "SetPausedParams",
return_value = "()",
error = "Error",
mutable,
enable_logger
)]
fn contract_set_paused<S: HasStateApi>(
ctx: &impl HasReceiveContext,
_host: &mut impl HasHost<State<S>, StateApiType = S>, // TODO rename _host to host
logger: &mut impl HasLogger,
) -> Result<()> {
let owner = ctx.owner();
let sender = ctx.sender();
ensure!(sender.matches_account(&owner), Error::NotOwner);
// let state = host.state_mut(); // TODO
let params: SetPausedParams = ctx.parameter_cursor().get()?;
// state.paused = params.paused; // TODO
logger.log(&BridgeEvent::SetPaused(SetPausedEvent {
paused: params.paused,
}))?;
Ok(())
}
#[receive(
contract = "Bridge",
name = "get_paused_status",
parameter = "()",
return_value = "bool",
error = "Error"
)]
fn get_paused_status<S: HasStateApi>(
_ctx: &impl HasReceiveContext,
_host: &impl HasHost<State<S>, StateApiType = S>, // TODO change _host to host
) -> Result<bool> {
// Ok(host.state().paused) // TODO
Ok(false) // TODO
}
#[receive(
contract = "Bridge",
name = "get_stable_commission_percent",
parameter = "()",
return_value = "u64",
error = "Error"
)]
fn get_stable_commission_percent<S: HasStateApi>(
_ctx: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<u16> {
Ok(host.state().default_percent)
}
#[receive(
contract = "Bridge",
name = "get_signer",
parameter = "()",
return_value = "String",
error = "Error"
)]
fn get_signer<S: HasStateApi>(
_: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<String> {
Ok(host
.state()
.default_signer
.map_or(String::new(), |s| s.to_string()))
}
#[receive(
contract = "Bridge",
name = "get_commission_collector",
parameter = "()",
return_value = "AccountAddress",
error = "Error"
)]
fn get_commission_collector<S: HasStateApi>(
_: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<AccountAddress> {
Ok(host.state().commission_collector)
}
#[receive(
contract = "Bridge",
name = "get_commission_by_token",
parameter = "ContractAddress",
return_value = "u128",
error = "Error"
)]
fn get_commission_by_token<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<u128> {
let contract: ContractAddress = ctx.parameter_cursor().get()?;
let commission_by_token = host
.state()
.commission_by_token
.get(&contract)
.map(|state_ref| *state_ref)
.unwrap_or(0);
Ok(commission_by_token)
}
#[receive(
contract = "Bridge",
name = "get_coin_commission",
parameter = "ContractAddress",
return_value = "u128",
error = "Error"
)]
fn get_coin_commission<S: HasStateApi>(
_: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<u128> {
Ok(host.state().commission_by_coin)
}
#[receive(
contract = "Bridge",
name = "get_bridge_coin_balance",
parameter = "()",
return_value = "u128",
error = "Error"
)]
fn get_bridge_coin_balance<S: HasStateApi>(
_: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<u128> {
Ok(host.self_balance().micro_ccd() as u128)
}
#[receive(
contract = "Bridge",
name = "get_total_commission",
parameter = "GetTotalCommissionParams",
return_value = "u128",
error = "Error"
)]
fn get_total_commission<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<u128> {
let params: GetTotalCommissionParams = ctx.parameter_cursor().get()?;
host.state()
.get_total_commission(params.amount, params.gas_commission)
}
#[receive(
contract = "Bridge",
name = "get_nonce",
parameter = "AccountAddress",
return_value = "Nonce",
error = "Error"
)]
fn get_nonce<S: HasStateApi>(
ctx: &impl HasReceiveContext,
host: &impl HasHost<State<S>, StateApiType = S>,
) -> Result<Nonce> {
let params: AccountAddress = ctx.parameter_cursor().get()?;
let nonce = host.state().user_nonces.get(¶ms).map_or(0, |n| *n);
Ok(nonce)
}