Skip to content

Commit

Permalink
contract-sdk/specs/token/oas20: Rollback if subcall fails in send
Browse files Browse the repository at this point in the history
  • Loading branch information
kostko committed Nov 7, 2022
1 parent 28a2e67 commit e1dc067
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
34 changes: 32 additions & 2 deletions contract-sdk/specs/token/oas20/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use oasis_contract_sdk::{
self as sdk,
env::Env,
types::{
message::{Message, NotifyReply},
message::{CallResult, Message, NotifyReply, Reply},
InstanceId,
},
};
Expand All @@ -14,6 +14,9 @@ use crate::types::{
TokenInstantiation,
};

/// Unique identifier for the send subcall.
pub const CALL_ID_SEND: u64 = 1;

/// Handles an OAS20 request call.
pub fn handle_call<C: sdk::Context>(
ctx: &mut C,
Expand All @@ -34,7 +37,16 @@ pub fn handle_call<C: sdk::Context>(
}
Request::Send { to, amount, data } => {
let from = ctx.caller_address().to_owned();
send(ctx, balances, from, to, amount, data, 0, NotifyReply::Never)?;
send(
ctx,
balances,
from,
to,
amount,
data,
CALL_ID_SEND,
NotifyReply::OnError, // Rollback if subcall fails.
)?;

ctx.emit_event(Event::Oas20Sent { from, to, amount });

Expand Down Expand Up @@ -120,6 +132,24 @@ pub fn handle_query<C: sdk::Context>(
}
}

/// Handles a reply from OAS20 execution.
pub fn handle_reply<C: sdk::Context>(
_ctx: &mut C,
_token_info: PublicCell<TokenInformation>,
_balances: PublicMap<Address, u128>,
_allowances: PublicMap<(Address, Address), u128>,
reply: Reply,
) -> Result<Option<Response>, Error> {
match reply {
Reply::Call {
id: CALL_ID_SEND,
result: CallResult::Failed { module, code },
..
} => Err(Error::ReceiverCallFailed(module, code)),
_ => Ok(None),
}
}

/// Instantiates the contract state.
pub fn instantiate<C: sdk::Context>(
ctx: &mut C,
Expand Down
6 changes: 5 additions & 1 deletion contract-sdk/specs/token/oas20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ extern crate alloc;
pub mod helpers;
pub mod types;

use oasis_contract_sdk::{self as sdk};
use oasis_contract_sdk::{self as sdk, types::message::Reply};
use oasis_contract_sdk_storage::{cell::PublicCell, map::PublicMap};
use oasis_contract_sdk_types::address::Address;

Expand Down Expand Up @@ -50,6 +50,10 @@ impl sdk::Contract for Oas20Token {
fn query<C: sdk::Context>(ctx: &mut C, request: Request) -> Result<Response, Error> {
helpers::handle_query(ctx, TOKEN_INFO, BALANCES, ALLOWANCES, request)
}

fn handle_reply<C: sdk::Context>(ctx: &mut C, reply: Reply) -> Result<Option<Response>, Error> {
helpers::handle_reply(ctx, TOKEN_INFO, BALANCES, ALLOWANCES, reply)
}
}

// Create the required WASM exports required for the contract to be runnable.
Expand Down
4 changes: 4 additions & 0 deletions contract-sdk/specs/token/oas20/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ pub enum Error {
#[error("insufficient allowance")]
#[sdk_error(code = 8)]
InsufficientAllowance,

#[error("receiver call failed (module: {0} code: {1})")]
#[sdk_error(code = 9)]
ReceiverCallFailed(String, u32),
}

/// All possible events that can be returned by the OAS20 contract.
Expand Down

0 comments on commit e1dc067

Please sign in to comment.