Skip to content

Commit

Permalink
Merge pull request #83 from arkprotocol/fix_back_transfer
Browse files Browse the repository at this point in the history
fix failed back transfer
  • Loading branch information
taitruong authored Jan 31, 2024
2 parents 09da354 + 545909f commit 1d96023
Show file tree
Hide file tree
Showing 13 changed files with 1,789 additions and 450 deletions.
32 changes: 18 additions & 14 deletions contracts/cw721-tester/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cosmwasm_schema::cw_serde;
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{Addr, Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdResult};
use cosmwasm_std::{Binary, Deps, DepsMut, Empty, Env, MessageInfo, Response, StdResult};
use cw2::set_contract_version;
use cw721_base::{msg, ContractError, Extension};
use cw_storage_plus::Item;
Expand All @@ -14,13 +14,13 @@ pub struct InstantiateMsg {
pub name: String,
pub symbol: String,
pub minter: String,
/// An address which will be unable to transfer NFTs away from
/// themselves (they are a black hole). If this address attempts a
/// `TransferNft` message it will fail with an out-of-gas error.
pub target: String,
/// An address which will be unable receive NFT on `TransferNft` message
/// If `TransferNft` message attempts sending to banned recipient
/// it will fail with an out-of-gas error.
pub banned_recipient: String,
}

const TARGET: Item<Addr> = Item::new("target");
const BANNED_RECIPIENT: Item<String> = Item::new("banned_recipient");

const CONTRACT_NAME: &str = "crates.io:cw721-gas-tester";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
Expand All @@ -43,7 +43,7 @@ pub fn instantiate(
withdraw_address: None,
},
)?;
TARGET.save(deps.storage, &deps.api.addr_validate(&msg.target)?)?;
BANNED_RECIPIENT.save(deps.storage, &msg.banned_recipient)?;
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;

Ok(response)
Expand All @@ -56,13 +56,17 @@ pub fn execute(
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
if matches!(msg, ExecuteMsg::TransferNft { .. }) && info.sender == TARGET.load(deps.storage)? {
// loop here causes the relayer to hang while it tries to
// simulate the TX.
panic!("gotem")
// loop {}
} else {
cw721_base::entry::execute(deps, env, info, msg)
match msg.clone() {
ExecuteMsg::TransferNft { recipient, .. } => {
if recipient == BANNED_RECIPIENT.load(deps.storage)? {
// loop here causes the relayer to hang while it tries to
// simulate the TX.
panic!("gotem")
// loop {}
}
cw721_base::entry::execute(deps, env, info, msg)
}
_ => cw721_base::entry::execute(deps, env, info, msg),
}
}

Expand Down
130 changes: 130 additions & 0 deletions packages/ics721/schema/ics721.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,74 @@
}
},
"additionalProperties": false
},
{
"description": "Admin msg in case something goes wrong. As a minimum it clean up states (incoming channel and token metadata), and burn NFT if exists.",
"type": "object",
"required": [
"admin_clean_and_burn_nft"
],
"properties": {
"admin_clean_and_burn_nft": {
"type": "object",
"required": [
"class_id",
"collection",
"owner",
"token_id"
],
"properties": {
"class_id": {
"type": "string"
},
"collection": {
"type": "string"
},
"owner": {
"type": "string"
},
"token_id": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "Admin msg in case something goes wrong. As a minimum it clean up state (outgoing channel), and transfer NFT if exists. - transfer NFT if exists",
"type": "object",
"required": [
"admin_clean_and_unescrow_nft"
],
"properties": {
"admin_clean_and_unescrow_nft": {
"type": "object",
"required": [
"class_id",
"collection",
"recipient",
"token_id"
],
"properties": {
"class_id": {
"type": "string"
},
"collection": {
"type": "string"
},
"recipient": {
"type": "string"
},
"token_id": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
Expand Down Expand Up @@ -245,6 +313,68 @@
},
"additionalProperties": false
},
{
"description": "Redeem all entries in outgoing channel.",
"type": "object",
"required": [
"redeem_outgoing_channel_entries"
],
"properties": {
"redeem_outgoing_channel_entries": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"$ref": "#/definitions/ClassId"
},
{
"$ref": "#/definitions/TokenId"
}
],
"maxItems": 2,
"minItems": 2
}
}
},
"additionalProperties": false
},
{
"description": "Save all entries in incoming channel.",
"type": "object",
"required": [
"add_incoming_channel_entries"
],
"properties": {
"add_incoming_channel_entries": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "array",
"items": [
{
"$ref": "#/definitions/ClassId"
},
{
"$ref": "#/definitions/TokenId"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "string"
}
],
"maxItems": 2,
"minItems": 2
}
}
},
"additionalProperties": false
},
{
"description": "Mints a NFT of collection class_id for receiver with the provided id and metadata. Only callable by this contract.",
"type": "object",
Expand Down
130 changes: 130 additions & 0 deletions packages/ics721/schema/raw/execute.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,74 @@
}
},
"additionalProperties": false
},
{
"description": "Admin msg in case something goes wrong. As a minimum it clean up states (incoming channel and token metadata), and burn NFT if exists.",
"type": "object",
"required": [
"admin_clean_and_burn_nft"
],
"properties": {
"admin_clean_and_burn_nft": {
"type": "object",
"required": [
"class_id",
"collection",
"owner",
"token_id"
],
"properties": {
"class_id": {
"type": "string"
},
"collection": {
"type": "string"
},
"owner": {
"type": "string"
},
"token_id": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"description": "Admin msg in case something goes wrong. As a minimum it clean up state (outgoing channel), and transfer NFT if exists. - transfer NFT if exists",
"type": "object",
"required": [
"admin_clean_and_unescrow_nft"
],
"properties": {
"admin_clean_and_unescrow_nft": {
"type": "object",
"required": [
"class_id",
"collection",
"recipient",
"token_id"
],
"properties": {
"class_id": {
"type": "string"
},
"collection": {
"type": "string"
},
"recipient": {
"type": "string"
},
"token_id": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
],
"definitions": {
Expand Down Expand Up @@ -112,6 +180,68 @@
},
"additionalProperties": false
},
{
"description": "Redeem all entries in outgoing channel.",
"type": "object",
"required": [
"redeem_outgoing_channel_entries"
],
"properties": {
"redeem_outgoing_channel_entries": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"$ref": "#/definitions/ClassId"
},
{
"$ref": "#/definitions/TokenId"
}
],
"maxItems": 2,
"minItems": 2
}
}
},
"additionalProperties": false
},
{
"description": "Save all entries in incoming channel.",
"type": "object",
"required": [
"add_incoming_channel_entries"
],
"properties": {
"add_incoming_channel_entries": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "array",
"items": [
{
"$ref": "#/definitions/ClassId"
},
{
"$ref": "#/definitions/TokenId"
}
],
"maxItems": 2,
"minItems": 2
},
{
"type": "string"
}
],
"maxItems": 2,
"minItems": 2
}
}
},
"additionalProperties": false
},
{
"description": "Mints a NFT of collection class_id for receiver with the provided id and metadata. Only callable by this contract.",
"type": "object",
Expand Down
15 changes: 15 additions & 0 deletions packages/ics721/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ pub enum ContractError {
#[error("NFT not escrowed by ICS721! Owner: {0}")]
NotEscrowedByIcs721(String),

#[error("{recipient} not owner of NFT {token_id}! Owner: {owner}")]
NotOwnerOfNft {
recipient: String,
owner: String,
token_id: String,
},

#[error("only unordered channels are supported")]
OrderedChannel {},

Expand All @@ -50,4 +57,12 @@ pub enum ContractError {

#[error("Couldn't find nft contract for this class id: {0}")]
NoNftContractForClassId(String),

#[error("Unknown nft contract: {child_collection}, Class Id: {class_id}, Token ID: {token_id} => NFT contract: {cw721_addr}")]
NoClassIdForNftContract {
child_collection: String,
class_id: String,
token_id: String,
cw721_addr: String,
},
}
Loading

0 comments on commit 1d96023

Please sign in to comment.