Skip to content

Commit

Permalink
Zkgm protocol channels (#3503)
Browse files Browse the repository at this point in the history
  • Loading branch information
hussein-aitlahcen authored Jan 14, 2025
2 parents 18c5c7e + 30b6ec2 commit f9b8810
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 14 deletions.
26 changes: 17 additions & 9 deletions cosmwasm/ibc-union/app/ucs03-zkgm/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,21 +720,29 @@ fn transfer(
if !contains_base_token {
return Err(ContractError::MissingFunds);
}
// If the origin exists, the preimage exists
let unwrapped_asset = HASH_TO_FOREIGN_TOKEN.may_load(deps.storage, base_token.clone())?;
let mut messages = Vec::<CosmosMsg<TokenFactoryMsg>>::new();
// TODO: handle forward path
let origin = TOKEN_ORIGIN.may_load(deps.storage, base_token.clone())?;
let mut origin = TOKEN_ORIGIN.may_load(deps.storage, base_token.clone())?;
match origin {
// Burn as we are going to unescrow on the counterparty
Some(path) if path == Uint256::from(channel_id) => messages.push(
TokenFactoryMsg::BurnTokens {
denom: base_token.clone(),
amount: base_amount,
burn_from_address: env.contract.address.into_string(),
}
.into(),
),
Some(path)
if path == Uint256::from(channel_id)
&& unwrapped_asset == Some(quote_token.clone()) =>
{
messages.push(
TokenFactoryMsg::BurnTokens {
denom: base_token.clone(),
amount: base_amount,
burn_from_address: env.contract.address.into_string(),
}
.into(),
)
}
// Escrow and update the balance, the counterparty will mint the token
_ => {
origin = None;
CHANNEL_BALANCE.update(deps.storage, (channel_id, base_token.clone()), |balance| {
match balance {
Some(value) => value
Expand Down
4 changes: 2 additions & 2 deletions docs/src/content/docs/protocol/deployments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ Deployments of `ibc-union` on CosmWasm (cosmos) chains. CosmWasm contract source

| Protocol | From | To | Channel |
|---------- |----------------- |---------- |--------- |
| ucs03 | 17000 | 11155111 | 5 |
| ucs03 | 11155111 | 17000 | 3 |
| ucs03 | 17000 | 11155111 | 9 |
| ucs03 | 11155111 | 17000 | 4 |
| ucs03 | 17000 | union-testnet-9 | 8 |
| ucs03 | union-testnet-9 | 17000 | 7 |
| ucs03 | 17000 | elgafar-1 | 11 |
Expand Down
24 changes: 23 additions & 1 deletion evm/contracts/apps/ucs/03-zkgm/Zkgm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import "@openzeppelin/token/ERC20/extensions/IERC20Metadata.sol";
import "solady/utils/CREATE3.sol";
import "solady/utils/LibBit.sol";
import "solady/utils/LibString.sol";
import "solady/utils/LibBytes.sol";

import "../../Base.sol";
import "../../../core/04-channel/IBCPacket.sol";
Expand Down Expand Up @@ -276,6 +277,7 @@ contract UCS03Zkgm is
{
using ZkgmLib for *;
using LibString for *;
using LibBytes for *;

IIBCPacket public ibcHandler;
mapping(bytes32 => IBCPacket) public inFlightPacket;
Expand Down Expand Up @@ -317,9 +319,18 @@ contract UCS03Zkgm is
string memory tokenName = sentTokenMeta.name();
string memory tokenSymbol = sentTokenMeta.symbol();
uint256 origin = tokenOrigin[baseToken];
if (ZkgmLib.lastChannelFromPath(origin) == channelId) {
// Verify the unwrap
(address wrappedToken,) =
internalPredictWrappedTokenMemory(0, channelId, quoteToken);
// Only allow unwrapping if the quote asset is the unwrapped asset.
if (
ZkgmLib.lastChannelFromPath(origin) == channelId
&& abi.encodePacked(baseToken).eq(abi.encodePacked(wrappedToken))
) {
IZkgmERC20(baseToken).burn(msg.sender, baseAmount);
} else {
// We reset the origin, the asset will not be unescrowed on the destination
origin = 0;
// TODO: extract this as a step before verifying to allow for ERC777
// send hook
SafeERC20.safeTransferFrom(
Expand Down Expand Up @@ -678,6 +689,17 @@ contract UCS03Zkgm is
return (wrappedToken, wrappedTokenSalt);
}

function internalPredictWrappedTokenMemory(
uint256 path,
uint32 channel,
bytes memory token
) internal view returns (address, bytes32) {
bytes32 wrappedTokenSalt = keccak256(abi.encode(path, channel, token));
address wrappedToken =
CREATE3.predictDeterministicAddress(wrappedTokenSalt);
return (wrappedToken, wrappedTokenSalt);
}

function predictWrappedToken(
uint256 path,
uint32 channel,
Expand Down
4 changes: 2 additions & 2 deletions evm/evm.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ _: {
solady = pkgs.fetchFromGitHub {
owner = "vectorized";
repo = "solady";
rev = "v0.0.253";
hash = "sha256-P8joH3RZvA2GijTVlRE6CmSSP730Q3zY8k9jiWflyDk=";
rev = "v0.0.292";
hash = "sha256-74No9at4wi0K0bgfjRUYMfvtg2NmWA7yY2MnM1jFAY0=";
};
forge-std = pkgs.fetchFromGitHub {
owner = "foundry-rs";
Expand Down

0 comments on commit f9b8810

Please sign in to comment.