Skip to content

Commit

Permalink
Add Hyperlane Transfer Action Support (#149)
Browse files Browse the repository at this point in the history
* add execute action

* add action and recover logic

* add cw20 logic

* update schema

* add tests for execute action

* implement hyperlane adapter

* implement hyperlane transfer action in entrypoint

* make schema

* remove unused import
  • Loading branch information
NotJeremyLiu authored Nov 6, 2024
1 parent c3757cb commit e2bffe6
Show file tree
Hide file tree
Showing 19 changed files with 559 additions and 35 deletions.
77 changes: 77 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 33 additions & 31 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"contracts/entry-point",
"contracts/adapters/hyperlane",
"contracts/adapters/ibc/*",
"contracts/adapters/swap/*",
"contracts/placeholder",
Expand All @@ -20,39 +21,40 @@ documentation = "https://github.com/skip-mev/skip-go-cosmwasm-contracts#readme"
keywords = ["cosmwasm"]

[workspace.dependencies]
astroport = "2.9"
astrovault = "0.1.8"
dexter = "1.4.0"
dexter-vault = "1.1.0"
astroport = "2.9"
astrovault = "0.1.8"
dexter = "1.4.0"
dexter-vault = "1.1.0"
dexter-stable-pool = "1.1.1"
dexter-weighted-pool = "1.1.1"
dexter-lp-token = "1.0.0"
dexter-router = "1.1.0"
cosmwasm-schema = "1.5.4"
cosmwasm-std = { version = "1.5.4", features = ["stargate"] }
cosmos-sdk-proto = { version = "0.19", default-features = false }
cw2 = "1.1"
cw20 = "1.1"
cw-storage-plus = "1"
cw-utils = "1.0.3"
cw-multi-test = "0.20.0"
ibc-proto = { version = "0.32.1", default-features = false }
lido-satellite = { git = "https://github.com/hadronlabs-org/lido-satellite", branch = "main", features = ["library"] }
drop-factory = { git = "https://github.com/hadronlabs-org/drop-contracts.git", branch = "feat/audit-fixes", features = ["library"] }
drop-staking-base = { git = "https://github.com/hadronlabs-org/drop-contracts.git", branch = "feat/audit-fixes", features = ["library"] }
mockall = "0.12.1"
neutron-proto = { version = "0.1.1", default-features = false, features = ["cosmwasm"] }
neutron-sdk = "0.10.0"
osmosis-std = "0.15.3"
prost = "0.11"
pryzm-std = "0.1.7"
serde = { version = "1.0.194", default-features = false, features = ["derive"] }
serde-cw-value = "0.7.0"
serde-json-wasm = "1.0.1"
skip = { version = "0.3.0", path = "./packages/skip" }
test-case = "3.3.1"
thiserror = "1"
white-whale-std = "1.1.1"
dexter-lp-token = "1.0.0"
dexter-router = "1.1.0"
cosmwasm-schema = "1.5.4"
cosmwasm-std = { version = "1.5.4", features = ["stargate"] }
cosmos-sdk-proto = { version = "0.19", default-features = false }
cw2 = "1.1"
cw20 = "1.1"
cw-storage-plus = "1"
cw-utils = "1.0.3"
cw-multi-test = "0.20.0"
hpl-interface = { git = "https://github.com/many-things/cw-hyperlane.git", branch = "main", features = ["library"] }
ibc-proto = { version = "0.32.1", default-features = false }
lido-satellite = { git = "https://github.com/hadronlabs-org/lido-satellite", branch = "main", features = ["library"] }
drop-factory = { git = "https://github.com/hadronlabs-org/drop-contracts.git", branch = "feat/audit-fixes", features = ["library"] }
drop-staking-base = { git = "https://github.com/hadronlabs-org/drop-contracts.git", branch = "feat/audit-fixes", features = ["library"] }
mockall = "0.12.1"
neutron-proto = { version = "0.1.1", default-features = false, features = ["cosmwasm"] }
neutron-sdk = "0.10.0"
osmosis-std = "0.15.3"
prost = "0.11"
pryzm-std = "0.1.7"
serde = { version = "1.0.194", default-features = false, features = ["derive"] }
serde-cw-value = "0.7.0"
serde-json-wasm = "1.0.1"
skip = { version = "0.3.0", path = "./packages/skip" }
test-case = "3.3.1"
thiserror = "1"
white-whale-std = "1.1.1"

[profile.release]
codegen-units = 1
Expand Down
36 changes: 36 additions & 0 deletions contracts/adapters/hyperlane/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "skip-go-hyperlane-adapter"
version = { workspace = true }
rust-version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
documentation = { workspace = true }
keywords = { workspace = true }

[lib]
crate-type = ["cdylib", "rlib"]

[features]
# for more explicit tests, cargo test --features=backtraces
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []

[dependencies]
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
cw2 = { workspace = true }
cw-storage-plus = { workspace = true }
cw-utils = { workspace = true }
hpl-interface = { workspace = true }
prost = { workspace = true }
serde-json-wasm = { workspace = true }
serde-cw-value = { workspace = true }
skip = { workspace = true }
thiserror = { workspace = true }

[dev-dependencies]
test-case = { workspace = true }
10 changes: 10 additions & 0 deletions contracts/adapters/hyperlane/src/bin/hyperlane-schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use cosmwasm_schema::write_api;
use skip::ibc::{ExecuteMsg, InstantiateMsg, QueryMsg};

fn main() {
write_api! {
instantiate: InstantiateMsg,
execute: ExecuteMsg,
query: QueryMsg
}
}
137 changes: 137 additions & 0 deletions contracts/adapters/hyperlane/src/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use crate::{
error::{ContractError, ContractResult},
state::ENTRY_POINT_CONTRACT_ADDRESS,
};
use cosmwasm_std::{entry_point, to_json_binary, DepsMut, Env, HexBinary, MessageInfo, Response};
use cw2::set_contract_version;
use cw_utils::one_coin;
use hpl_interface::warp::native::ExecuteMsg::TransferRemote;
use skip::{
asset::Asset,
hyperlane::{ExecuteMsg, InstantiateMsg, MigrateMsg},
};

///////////////
/// MIGRATE ///
///////////////

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut, _env: Env, msg: MigrateMsg) -> ContractResult<Response> {
// Set contract version
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

// Validate entry point contract address
let checked_entry_point_contract_address =
deps.api.addr_validate(&msg.entry_point_contract_address)?;

// Store the entry point contract address
ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?;

Ok(Response::new()
.add_attribute("action", "migrate")
.add_attribute(
"entry_point_contract_address",
checked_entry_point_contract_address.to_string(),
))
}

///////////////////
/// INSTANTIATE ///
///////////////////

// Contract name and version used for migration.
const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
msg: InstantiateMsg,
) -> ContractResult<Response> {
// Set contract version
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

// Validate entry point contract address
let checked_entry_point_contract_address =
deps.api.addr_validate(&msg.entry_point_contract_address)?;

// Store the entry point contract address
ENTRY_POINT_CONTRACT_ADDRESS.save(deps.storage, &checked_entry_point_contract_address)?;

Ok(Response::new()
.add_attribute("action", "instantiate")
.add_attribute(
"entry_point_contract_address",
checked_entry_point_contract_address.to_string(),
))
}

///////////////
/// EXECUTE ///
///////////////

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
_env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> ContractResult<Response> {
match msg {
ExecuteMsg::HplTransfer {
dest_domain,
recipient,
hook,
metadata,
warp_address,
} => execute_hpl_transfer(
deps,
info,
dest_domain,
recipient,
hook,
metadata,
warp_address,
),
}
}

// Converts the given info and coin into a Hyperlane remote transfer
fn execute_hpl_transfer(
deps: DepsMut,
info: MessageInfo,
dest_domain: u32,
recipient: HexBinary,
hook: Option<String>,
metadata: Option<HexBinary>,
warp_address: String,
) -> ContractResult<Response> {
// Get entry point contract address from storage
let entry_point_contract_address = ENTRY_POINT_CONTRACT_ADDRESS.load(deps.storage)?;

// Enforce the caller is the entry point contract
if info.sender != entry_point_contract_address {
return Err(ContractError::Unauthorized);
}

// Get the asset from the info
let asset: Asset = one_coin(&info)?.into();

// Create the Hyperlane remote transfer message
let msg = to_json_binary(&TransferRemote {
dest_domain,
recipient,
amount: asset.amount(),
hook,
metadata,
})?;

// Convert the hyperlane transfer message into a wasm message
let hpl_msg = asset.into_wasm_msg(warp_address, msg)?;

Ok(Response::new()
.add_message(hpl_msg)
.add_attribute("action", "execute_hyperlane_transfer"))
}
Loading

0 comments on commit e2bffe6

Please sign in to comment.