-
Notifications
You must be signed in to change notification settings - Fork 9
feat: UnionTransfer EVM library #323
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
Open
keyleu
wants to merge
14
commits into
main
Choose a base branch
from
keyne/union-transfer-evm-library
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
b8aefe3
library with unit tests
keyleu 19b6cc8
add comment
keyleu b56ecc1
e2e tests for union
keyleu 6b082aa
change test
keyleu 07f56c8
encoding
keyleu 76928d2
Add docs
keyleu 1cb336b
Merge branch 'main' into keyne/union-transfer-evm-library
keyleu f6e9804
coderabbit suggestions
keyleu 5756cf2
fix comment
keyleu b7b09fb
improve doc section
keyleu 01de34f
Merge branch 'main' into keyne/union-transfer-evm-library
keyleu a3f6fe6
adjust changes for mock erc 20
keyleu ef6d2f7
merge main
keyleu 01c1b39
Merge branch 'main' into keyne/union-transfer-evm-library
keyleu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
This file contains hidden or 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
110 changes: 110 additions & 0 deletions
110
contracts/encoders/evm-encoder/src/libraries/union_transfer.rs
This file contains hidden or 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
use alloy_primitives::Bytes; | ||
use alloy_sol_types::{SolCall, SolValue}; | ||
use cosmwasm_schema::cw_serde; | ||
use cosmwasm_std::{Binary, StdError, StdResult, Uint256}; | ||
use valence_encoder_utils::libraries::{ | ||
union_transfer::solidity_types::transferCall, updateConfigCall, | ||
}; | ||
use valence_library_utils::{msg::ExecuteMsg, LibraryAccountType}; | ||
|
||
use crate::parse_address; | ||
|
||
use super::{get_update_ownership_call, get_update_processor_call}; | ||
|
||
// We need to define a config and functions for this library as we don't have a CosmWasm equivalent | ||
#[cw_serde] | ||
/// Struct representing the library configuration. | ||
pub struct LibraryConfig { | ||
/// The input address for the library. | ||
pub input_addr: LibraryAccountType, | ||
/// The recipient of the transfer on the destination chain (for bech32 addresses the bytes conversion of the entire bech32 address string). | ||
pub recipient: Binary, | ||
/// Amount to transfer. Setting this to 0 will transfer the entire balance. | ||
pub amount: Uint256, | ||
/// Address of the zkGM contract. | ||
pub zk_gm: String, | ||
/// The address of the ERC20 token. | ||
pub transfer_token: String, | ||
/// The name of the transfer token. | ||
pub transfer_token_name: String, | ||
/// The symbol of the transfer token. | ||
pub transfer_token_symbol: String, | ||
/// The decimals of the transfer token. | ||
pub transfer_token_decimals: u8, | ||
/// The token requested in return on destination chain. Bytes conversion of the token denom / address for Native Cosmos Tokens / CW-20 tokens. | ||
pub quote_token: Binary, | ||
/// The amount of the quote token. | ||
pub quote_token_amount: Uint256, | ||
/// The path to unwrap the transfer token. | ||
pub transfer_token_unwrapping_path: Uint256, | ||
/// The channel ID for the transfer. | ||
pub channel_id: u32, | ||
/// The timeout for the transfer. | ||
pub timeout: u64, | ||
/// The protocol version for the transfer. | ||
pub protocol_version: u8, | ||
} | ||
|
||
#[cw_serde] | ||
/// Enum representing the different function messages that can be sent. | ||
pub enum FunctionMsgs { | ||
/// Message to transfer tokens. | ||
/// If the quote amount is not passed, the value in the config will be used. | ||
Transfer { quote_amount: Option<Uint256> }, | ||
} | ||
|
||
type UnionTransferConfig = ExecuteMsg<FunctionMsgs, LibraryConfig>; | ||
|
||
pub fn encode(msg: &Binary) -> StdResult<Vec<u8>> { | ||
// Extract the message from the binary and verify that it parses into a valid json for the library | ||
let msg: UnionTransferConfig = serde_json::from_slice(msg.as_slice()).map_err(|_| { | ||
StdError::generic_err("Message sent is not a valid message for this library!".to_string()) | ||
})?; | ||
|
||
match msg { | ||
ExecuteMsg::ProcessFunction(function) => match function { | ||
FunctionMsgs::Transfer { quote_amount } => { | ||
let transfer_call = transferCall { | ||
_quoteAmount: alloy_primitives::U256::from_be_bytes( | ||
quote_amount.unwrap_or_default().to_be_bytes(), | ||
), | ||
}; | ||
Ok(transfer_call.abi_encode()) | ||
} | ||
}, | ||
ExecuteMsg::UpdateConfig { new_config } => { | ||
// Parse addresses | ||
let input_account = parse_address(&new_config.input_addr.to_string()?)?; | ||
let zk_gm = parse_address(&new_config.zk_gm)?; | ||
// Convert to address to verify it is a valid address | ||
let transfer_token = parse_address(&new_config.transfer_token)?; | ||
|
||
// Build config struct | ||
keyleu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let config = | ||
valence_encoder_utils::libraries::union_transfer::solidity_types::UnionTransferConfig { | ||
protocolVersion: new_config.protocol_version, | ||
transferTokenDecimals: new_config.transfer_token_decimals, | ||
channelId: new_config.channel_id, | ||
timeout: new_config.timeout, | ||
inputAccount: input_account, | ||
zkGM: zk_gm, | ||
amount: alloy_primitives::U256::from_be_bytes(new_config.amount.to_be_bytes()), | ||
quoteTokenAmount: alloy_primitives::U256::from_be_bytes(new_config.quote_token_amount.to_be_bytes()), | ||
transferTokenUnwrappingPath: alloy_primitives::U256::from_be_bytes(new_config.transfer_token_unwrapping_path.to_be_bytes()), | ||
recipient: new_config.recipient.to_vec().into(), | ||
transferToken: Bytes::from(transfer_token.to_vec()), | ||
quoteToken: new_config.quote_token.to_vec().into(), | ||
transferTokenName: new_config.transfer_token_name, | ||
transferTokenSymbol: new_config.transfer_token_symbol, | ||
}; | ||
keyleu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Create the encoded call with the encoded config | ||
let call = updateConfigCall { | ||
_config: config.abi_encode().into(), | ||
}; | ||
Ok(call.abi_encode()) | ||
} | ||
ExecuteMsg::UpdateProcessor { processor } => get_update_processor_call(&processor), | ||
ExecuteMsg::UpdateOwnership(action) => get_update_ownership_call(action), | ||
} | ||
} |
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Valence Union Transfer library | ||
|
||
The **Valence Union Transfer** library allows to **transfer funds** from an **input account** to a **recipient** using the [Union UCS03-ZKGM protocol](https://docs.union.build/ucs/03/), which allows arbitrary filling of orders by any party. It is typically used as part of a **Valence Program**. In that context, a **Processor** contract will be the main contract interacting with the Union Transfer library. | ||
|
||
## High-level flow | ||
|
||
```mermaid | ||
--- | ||
title: Union Transfer Library | ||
--- | ||
graph LR | ||
IA((Input Account)) | ||
ZG((zkGM)) | ||
R((Recipient)) | ||
P[Processor] | ||
U[Union Transfer | ||
Library] | ||
UTM[Union Token | ||
Protocol] | ||
|
||
subgraph DEST[ Destination Chain ] | ||
UTM -- 6/Send tokens --> R | ||
end | ||
|
||
subgraph EVM[ EVM Domain ] | ||
P -- 1/Call | ||
transfer(quoteAmount) --> U | ||
U -- 2/Query ERC20 balance --> IA | ||
U -- 3/Call approve and send --> IA | ||
IA -- 4/Approve ERC20 --> ZG | ||
IA -- 5/Call send with instruction --> ZG | ||
end | ||
|
||
EVM --- DEST | ||
``` | ||
|
||
## Functions | ||
|
||
| Function | Parameters | Description | | ||
| ------------ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| **Transfer** | quoteAmount | Transfer funds from the configured **input account** to the **recipient** on the **destination chain**. The quoteAmount parameter can override the configured quote token amount. If 0 is passed, the amount in the config is used. | | ||
|
||
## Configuration | ||
|
||
The library is configured on deployment using the `UnionTransferConfig` type. A list of supported chains and their channels can be found [here](https://docs.union.build/protocol/chains/overview/). Additional information of parameters used in the configuration can be found [here](https://docs.union.build/ucs/03/). This library allows any party to fill orders, therefore the `quoteTokenAmount` value should take into consideration the amount of tokens that the filling party will receive. | ||
|
||
All current deployed Union UCS03 contracts can be found in the [deployment section](https://docs.union.build/protocol/deployments/) under the name `ucs03`. | ||
|
||
```solidity | ||
/** | ||
* @dev Configuration struct for Union transfer parameters. | ||
* | ||
* -- Transfer core parameters -- | ||
* @param amount The number of tokens to transfer. If set to 0, the entire balance is transferred. | ||
* @param inputAccount The account from which tokens will be debited. | ||
* @param recipient The recipient (in Bytes format) on the destination chain where tokens will be received. | ||
* For bech32 addresses, it just converts the entire address to bytes. For example the bytes representation | ||
* of `bbn14mlpd48k5vkeset4x7f78myz3m47jcaxz9gpnl` would be | ||
* `0x62626e31346d6c706434386b35766b657365743478376637386d797a336d34376a6361787a3967706e6c` | ||
* | ||
* -- Transfer token details -- | ||
* @param transferToken The ERC20 token address that will be transferred. | ||
* @param transferTokenName The name of the token being transferred (e.g., "Babylon") | ||
* @param transferTokenSymbol The symbol of the token being transferred. (e.g., "BABY") | ||
* @param transferTokenDecimals The number of decimals for the token being transferred. (e.g., 6) | ||
* @param transferTokenUnwrappingPath Origin path for unwrapping, (e.g., 0 for WETH, 1 for BABY...). Related to the origin chain of these tokens. | ||
* | ||
* -- Quote token details -- | ||
* @param quoteToken The token requested in return on destination chain. Bytes conversion of the token. | ||
* For example, the quote Token for WETH on Babylon would be `0x62626e31333030736530767775653737686e36733877706836346579366435357a616634386a72766567397761667371756e636e33653473637373677664` | ||
* which bytes conversion of "bbn1300se0vwue77hn6s8wph64ey6d55zaf48jrveg9wafsquncn3e4scssgvd" because WETH is a CW20 token on Babylon. | ||
* For BABY, on the other side, it would be `0x7562626e` which is the bytes conversion of "ubbn". | ||
* @param quoteTokenAmount The amount of the quote token requested in return on the destination chain. If set to 0, the same amount as the transferred token is requested. | ||
* | ||
* -- Protocol parameters -- | ||
* @param zkGM The zkGM contract. | ||
* @param protocolVersion The protocol version to be used. Required for backward compatibility. Allows dispatching between different versions. | ||
* @param channelId The channel ID for the transfer. This is used to identify the specific transfer channel. | ||
* @param timeout The timeout in seconds for the transfer. For reference, 3 days is being used on btc.union.build (259200 seconds). | ||
*/ | ||
struct UnionTransferConfig { | ||
uint8 protocolVersion; | ||
uint8 transferTokenDecimals; | ||
uint32 channelId; | ||
uint64 timeout; | ||
BaseAccount inputAccount; | ||
IUnion zkGM; | ||
uint256 amount; | ||
uint256 quoteTokenAmount; | ||
uint256 transferTokenUnwrappingPath; | ||
bytes recipient; | ||
bytes transferToken; | ||
bytes quoteToken; | ||
string transferTokenName; | ||
string transferTokenSymbol; | ||
} | ||
``` |
This file contains hidden or 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
This file contains hidden or 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod solidity_types; |
22 changes: 22 additions & 0 deletions
22
packages/encoder-utils/src/libraries/union_transfer/solidity_types.rs
This file contains hidden or 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
use alloy_sol_types::sol; | ||
|
||
sol! { | ||
struct UnionTransferConfig { | ||
uint8 protocolVersion; | ||
uint8 transferTokenDecimals; | ||
uint32 channelId; | ||
uint64 timeout; | ||
address inputAccount; | ||
address zkGM; | ||
uint256 amount; | ||
uint256 quoteTokenAmount; | ||
uint256 transferTokenUnwrappingPath; | ||
bytes recipient; | ||
bytes transferToken; | ||
bytes quoteToken; | ||
string transferTokenName; | ||
string transferTokenSymbol; | ||
} | ||
|
||
function transfer(uint256 _quoteAmount) external; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.