-
Notifications
You must be signed in to change notification settings - Fork 31
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
Incoming proxy #76
Incoming proxy #76
Conversation
/// Being called on receiving the NFT before transfer is completed. (destination side) | ||
/// `on_recieve` hook | ||
/// Note - Failing this message will fail the transfer. | ||
Ics721ReceivePacketMsg { | ||
packet: IbcPacket, | ||
data: NonFungibleTokenPacketData, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case optional incoming proxy is set, during ibc_packet_receive
this msg is called on proxy.
let data: NonFungibleTokenPacketData = from_json(&packet.data)?; | ||
data.validate()?; | ||
|
||
// If there is an incoming proxy, let proxy validate the packet, in case it fails, we fail the transfer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's where incoming proxy is getting called on target chain. In case proxy throws an error, NFT is returned back to soure chain. For details check here: https://github.com/arkprotocol/cw721-proxy/blob/main/packages/cw-incoming-proxy/src/lib.rs#L44-L56
@@ -2025,7 +2073,8 @@ fn test_migration() { | |||
new_code_id: test.ics721_id, | |||
msg: to_json_binary(&MigrateMsg::WithUpdate { | |||
pauser: None, | |||
proxy: None, | |||
incoming_proxy: None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test migration
ts-relayer-tests/src/ics721.spec.ts
Outdated
@@ -186,6 +244,115 @@ test.serial("transfer NFT", async (t) => { | |||
t.is(osmoAddr, tokenOwner.owner); | |||
}); | |||
|
|||
test.serial("transfer NFT with incoming proxy: osmo -> wasmd", async (t) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
relayer test for incoming proxy with 2 scenarios:
- nft send to WLed channel
- nft send to unknown channel
ts-relayer-tests/src/ics721.spec.ts
Outdated
nft_contract: { class_id: wasmClassId }, | ||
}); | ||
|
||
tokenOwner = await ownerOf(wasmClient, wasmCw721, tokenId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scenario 1: NFT received on target chain
ts-relayer-tests/src/ics721.spec.ts
Outdated
// assert NFT on chain A is returned to owner | ||
tokenOwner = await ownerOf(osmoClient, osmoCw721, tokenId); | ||
t.is(osmoClient.senderAddress, tokenOwner.owner); | ||
t.log(`NFT #${tokenId} returned to owner`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scenario 2: NFT returned to source chain.
f112d26
to
60277c0
Compare
// use by default ClassId, in case there's no class data with name and symbol | ||
let mut instantiate_msg = cw721_base::msg::InstantiateMsg { | ||
name: class.id.clone().into(), | ||
symbol: class.id.clone().into(), | ||
minter: env.contract.address.to_string(), | ||
withdraw_address: Some(creator), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow creator of ics721 for setting withdraw address on nft contract (allowing to send and withdraw funds). This affected only ics721-base for permissionless chains.
sg-ics721 is unchanged.
More on withdraw address, see here: public-awesome/cw-nfts#149
} | ||
|
||
impl<'a> Bounder<'a> for ClassId { | ||
fn inclusive_bound(self) -> Option<cw_storage_plus::Bound<'a, Self>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly is this doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed in query_nft_contracts()
since paginated query requires a bounder. Simple need trick for inferring a bounder: https://github.com/arkprotocol/ark-cw-ics721/blob/incoming_proxy/packages/ics721/src/query.rs#L138
Bounder defined here: https://github.com/DA0-DA0/dao-contracts/blob/v2.4.0/packages/cw-paginate-storage/src/lib.rs#L18
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well my question is, it seems like the code is just copy paste something that already exists? Doesn't it already get this functionality through an import? What specifically is changing in the override?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it doesn't exist yet. If I dont implement bounder, then I have to explicitely provide bounder in query.
Done - description added above. |
test.serial( | ||
"transfer NFT with osmo outgoing and wasm incoming proxy", | ||
async (t) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NEW: added ts-relayer integration test for:
- ics721 handles incoming msg from outgoing proxy properly
- ics721 passes ibc packet to incoming proxy
- success: in case packet is coming from WLed channel
- fail: in case channel is not WLed -> NFT returned back to onwer on source chain
}) => self.execute_receive_nft(deps, env, info, token_id, sender, msg), | ||
ExecuteMsg::ReceiveProxyNft { eyeball, msg } => { | ||
self.execute_receive_proxy_nft(deps, env, info, eyeball, msg) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReceiveProxyNft
has been removed, instead ReceiveNft
handles both: msgs from collection and outgoing proxy contract
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
Similar to outgoing proxy (for source chain), this PR adds an optional incoming proxy for target chain. In case an incoming proxy is defined, incoming
IbcPacket
andNonFungibleTokenPacketData
is passed to proxy.A default implementation can be found here: https://github.com/arkprotocol/cw721-proxy/tree/main/contracts/cw721-incoming-proxy
The incoming proxy validates from which channel (=chain and ics721)
IbcPacket
is coming from. In case channel is not whitelisted anUnauthorizedSourceChannel
is thrown.An incoming proxy is needed in case chain or ics721 on source/other chain has been compromised.