Skip to content

Commit

Permalink
feat(ucs01): respect ics20 bearishness (#770)
Browse files Browse the repository at this point in the history
  • Loading branch information
hussein-aitlahcen authored Oct 3, 2023
2 parents ae85ee1 + 55bb9ad commit 2369eaa
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 129 deletions.
91 changes: 4 additions & 87 deletions cosmwasm/ucs01-relay/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,54 +72,6 @@ fn decrease_outstanding(
})
}

fn update_in_flight<F>(
deps: DepsMut,
channel_id: &str,
denom: &str,
f: F,
) -> Result<(), ContractError>
where
F: FnOnce(Option<Uint512>) -> Result<Uint512, ContractError>,
{
CHANNEL_STATE.update(
deps.storage,
(channel_id, &denom),
|state| -> Result<_, ContractError> {
let new_in_flight = f(state.as_ref().map(|x| x.in_flight))?;
let mut state = state.unwrap_or_default();
state.in_flight = new_in_flight;
Ok(state)
},
)?;
Ok(())
}

fn increase_in_flight(
deps: DepsMut,
channel_id: &str,
denom: &str,
amount: Uint128,
) -> Result<(), ContractError> {
update_in_flight(deps, channel_id, denom, |in_flight| {
let new_in_flight = in_flight.unwrap_or_default().checked_add(amount.into())?;
Ok(new_in_flight)
})
}

fn decrease_in_flight<'a>(
deps: DepsMut<'a>,
channel_id: &str,
denom: &str,
amount: Uint128,
) -> Result<(), ContractError> {
update_in_flight(deps, channel_id, denom, |in_flight| {
let new_in_flight = in_flight
.ok_or(ContractError::InsufficientFunds)?
.checked_sub(amount.into())?;
Ok(new_in_flight)
})
}

trait OnReceive {
fn foreign_toggle(&mut self, denom: &str) -> Result<bool, ContractError>;

Expand Down Expand Up @@ -268,7 +220,7 @@ impl<'a> ForTokens for StatefulSendTokens<'a> {
denom: &str,
amount: Uint128,
) -> Result<Vec<CosmosMsg<TokenFactoryMsg>>, ContractError> {
increase_in_flight(self.deps.branch(), channel_id, denom, amount)?;
increase_outstanding(self.deps.branch(), channel_id, denom, amount)?;
Ok(Default::default())
}

Expand Down Expand Up @@ -299,7 +251,7 @@ impl<'a> ForTokens for StatefulRefundTokens<'a> {
denom: &str,
amount: Uint128,
) -> Result<Vec<CosmosMsg<TokenFactoryMsg>>, ContractError> {
decrease_in_flight(self.deps.branch(), channel_id, denom, amount)?;
decrease_outstanding(self.deps.branch(), channel_id, denom, amount)?;
Ok(vec![BankMsg::Send {
to_address: self.receiver.clone(),
amount: vec![Coin {
Expand All @@ -325,33 +277,6 @@ impl<'a> ForTokens for StatefulRefundTokens<'a> {
}
}

struct StatefulLandedTokens<'a> {
deps: DepsMut<'a>,
}

impl<'a> ForTokens for StatefulLandedTokens<'a> {
// When a local token landed in the counterparty chain, it is no longer considered in-flight
fn on_local(
&mut self,
channel_id: &str,
denom: &str,
amount: Uint128,
) -> Result<Vec<CosmosMsg<TokenFactoryMsg>>, ContractError> {
decrease_in_flight(self.deps.branch(), channel_id, denom, amount)?;
increase_outstanding(self.deps.branch(), channel_id, denom, amount)?;
Ok(Default::default())
}

fn on_remote(
&mut self,
_channel_id: &str,
_denom: &str,
_amount: Uint128,
) -> Result<Vec<CosmosMsg<TokenFactoryMsg>>, ContractError> {
Ok(Default::default())
}
}

pub struct ProtocolCommon<'a> {
pub deps: DepsMut<'a>,
pub env: Env,
Expand Down Expand Up @@ -415,17 +340,9 @@ impl<'a> TransferProtocol for Ics20Protocol<'a> {
&mut self,
_sender: &str,
_receiver: &str,
tokens: Vec<TransferToken>,
_tokens: Vec<TransferToken>,
) -> Result<Vec<CosmosMsg<Self::CustomMsg>>, Self::Error> {
StatefulLandedTokens {
deps: self.common.deps.branch(),
}
.execute(
&self.common.env.contract.address,
&self.common.channel.endpoint.channel_id,
&self.common.channel.counterparty_endpoint,
tokens,
)
Ok(Default::default())
}

fn send_tokens_failure(
Expand Down
50 changes: 8 additions & 42 deletions evm/contracts/apps/ucs/01-relay/Relay.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ contract UCS01Relay is IBCAppBase {
public counterpartyEndpoints;
mapping(string => mapping(string => mapping(address => uint256)))
public outstanding;
mapping(string => mapping(string => mapping(address => uint256)))
public inFlight;

event DenomCreated(string denom, address token);
event Received(
Expand Down Expand Up @@ -162,26 +160,6 @@ contract UCS01Relay is IBCAppBase {
].sub(amount);
}

function increaseInFlight(
string memory portId,
string memory channelId,
address token,
uint256 amount
) internal {
inFlight[portId][channelId][token] = inFlight[portId][channelId][token]
.add(amount);
}

function decreaseInFlight(
string memory portId,
string memory channelId,
address token,
uint256 amount
) internal {
inFlight[portId][channelId][token] = inFlight[portId][channelId][token]
.sub(amount);
}

function send(
string calldata portId,
string calldata channelId,
Expand Down Expand Up @@ -211,7 +189,7 @@ contract UCS01Relay is IBCAppBase {
localToken.amount
);
} else {
increaseInFlight(
increaseOutstanding(
portId,
channelId,
localToken.denom,
Expand Down Expand Up @@ -263,34 +241,22 @@ contract UCS01Relay is IBCAppBase {
} else {
// It must be in the form 0x...
denomAddress = hexToAddress(token.denom);
// The token must be in-flight
decreaseInFlight(portId, channelId, denomAddress, token.amount);
decreaseOutstanding(
portId,
channelId,
denomAddress,
token.amount
);
IERC20(denomAddress).transfer(receiver, token.amount);
}
}
}

// We received a successful ack, move tokens from in-flight to outstanding.
function tokensLanded(
string memory portId,
string memory channelId,
RelayPacket memory packet
) internal {
for (uint256 i = 0; i < packet.tokens.length; i++) {
Token memory token = packet.tokens[i];
// For local tokens only as remote tokens are burnt.
if (token.denom.toSlice().startsWith("0x".toSlice())) {
address denomAddress = hexToAddress(token.denom);
decreaseInFlight(portId, channelId, denomAddress, token.amount);
increaseOutstanding(
portId,
channelId,
denomAddress,
token.amount
);
}
}
}
) internal {}

function onRecvPacketProcessing(
IbcCoreChannelV1Packet.Data calldata ibcPacket,
Expand Down

0 comments on commit 2369eaa

Please sign in to comment.