diff --git a/contracts/consumer/converter/src/contract.rs b/contracts/consumer/converter/src/contract.rs index 5f2b0da3..894761b0 100644 --- a/contracts/consumer/converter/src/contract.rs +++ b/contracts/consumer/converter/src/contract.rs @@ -640,11 +640,12 @@ impl ConverterApi for ConverterContract<'_> { let channel = IBC_CHANNEL.load(ctx.deps.storage)?; // Recalculate the price when unbond - let amount = self.invert_price(ctx.deps.as_ref(), amount)?; + let inverted_amount = self.invert_price(ctx.deps.as_ref(), amount.clone())?; let packet = ConsumerPacket::InternalUnstake { delegator, validator, - amount, + normalize_amount: amount, + inverted_amount, }; let msg = IbcMsg::SendPacket { channel_id: channel.endpoint.channel_id, diff --git a/contracts/consumer/converter/src/ibc.rs b/contracts/consumer/converter/src/ibc.rs index 875809b3..0c8fb107 100644 --- a/contracts/consumer/converter/src/ibc.rs +++ b/contracts/consumer/converter/src/ibc.rs @@ -273,14 +273,16 @@ pub fn ibc_packet_ack( if let ConsumerPacket::InternalUnstake { delegator, validator, - amount, + normalize_amount, + inverted_amount: _, } = packet { + // execute virtual contract's internal unbond let msg = virtual_staking_api::sv::ExecMsg::InternalUnbond { delegator, validator, - amount, + amount: normalize_amount, }; let msg = WasmMsg::Execute { contract_addr: contract.virtual_stake.load(deps.storage)?.into(), diff --git a/contracts/consumer/virtual-staking/src/contract.rs b/contracts/consumer/virtual-staking/src/contract.rs index b087cd47..a6a302bc 100644 --- a/contracts/consumer/virtual-staking/src/contract.rs +++ b/contracts/consumer/virtual-staking/src/contract.rs @@ -495,7 +495,7 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { fn internal_unbond( &self, ctx: ExecCtx, - _delegator: String, + delegator: String, validator: String, amount: Coin, ) -> Result, Self::Error> { @@ -526,7 +526,19 @@ impl VirtualStakingApi for VirtualStakingContract<'_> { ) .collect::>()?; self.bonded.save(ctx.deps.storage, &requests)?; - Ok(Response::new()) + + let mut msgs: Vec<_> = vec![]; + msgs.push(VirtualStakeMsg::UpdateDelegation { + amount: amount.clone(), + is_deduct: true, + delegator, + validator: validator.clone(), + }); + msgs.push(VirtualStakeMsg::Unbond { + amount, + validator, + }); + Ok(Response::new().add_messages(msgs)) } // FIXME: need to handle custom message types and queries diff --git a/contracts/provider/external-staking/src/contract.rs b/contracts/provider/external-staking/src/contract.rs index d2684505..cd3a93c3 100644 --- a/contracts/provider/external-staking/src/contract.rs +++ b/contracts/provider/external-staking/src/contract.rs @@ -467,8 +467,8 @@ impl ExternalStakingContract<'_> { // Commit sub amount, saturating if slashed let amount = min(amount.amount, stake.stake.high()); - stake.stake.commit_sub(amount); - + stake.stake.sub(amount, Uint128::zero())?; + let unbond = PendingUnbond { amount, release_at: env.block.time, diff --git a/contracts/provider/external-staking/src/ibc.rs b/contracts/provider/external-staking/src/ibc.rs index 42cf9328..b054d7ec 100644 --- a/contracts/provider/external-staking/src/ibc.rs +++ b/contracts/provider/external-staking/src/ibc.rs @@ -158,9 +158,10 @@ pub fn ibc_packet_receive( ConsumerPacket::InternalUnstake { delegator, validator, - amount, + normalize_amount: _, + inverted_amount, } => { - let evt = contract.internal_unstake(deps, env, delegator, validator, amount)?; + let evt = contract.internal_unstake(deps, env, delegator, validator, inverted_amount)?; let ack = ack_success(&DistributeAck {})?; IbcReceiveResponse::new().set_ack(ack).add_event(evt) } diff --git a/packages/apis/src/ibc/packet.rs b/packages/apis/src/ibc/packet.rs index c873f697..86bdac64 100644 --- a/packages/apis/src/ibc/packet.rs +++ b/packages/apis/src/ibc/packet.rs @@ -120,7 +120,8 @@ pub enum ConsumerPacket { /// This is the local (provider-side) denom that is held in the vault. /// It will be converted to the consumer-side staking token in the converter with help /// of the price feed. - amount: Coin, + normalize_amount: Coin, + inverted_amount: Coin, }, /// This is part of the rewards protocol Distribute {