Skip to content
Merged

Patch #170

Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
update: handle err
  • Loading branch information
aurexav committed Dec 17, 2019
commit f2c53e733d484585c36744408a6cb6a0018eeb94
158 changes: 94 additions & 64 deletions srml/eth-backing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

//use codec::{Decode, Encode};
use ethabi::{Event as EthEvent, EventParam as EthEventParam, ParamType, RawLog};
use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec, vec::Vec}; // fmt::Debug
use rstd::{borrow::ToOwned, convert::TryFrom, marker::PhantomData, result, vec}; // fmt::Debug
use sr_primitives::traits::{SaturatedConversion, Saturating};
use support::{decl_event, decl_module, decl_storage, ensure, traits::Currency, traits::OnUnbalanced}; // dispatch::Result,
use system::ensure_signed; // Convert,
Expand Down Expand Up @@ -83,6 +83,8 @@ decl_module! {
where
origin: T::Origin
{
// event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data)
// https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800
pub fn redeem_ring(origin, proof_record: EthReceiptProof) {
let _relayer = ensure_signed(origin)?;

Expand All @@ -91,7 +93,7 @@ decl_module! {
"Ring For This Proof - ALREADY BEEN REDEEMED",
);

let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "RingBurndropTokens")?;
let (darwinia_account, redeemed_amount) = Self::parse_token_redeem_proof(&proof_record, "RingBurndropTokens")?;
let redeemed_ring = <RingBalanceOf<T>>::saturated_from(redeemed_amount);
let redeemed_positive_imbalance_ring = T::Ring::deposit_into_existing(&darwinia_account, redeemed_ring)?;

Expand All @@ -103,7 +105,7 @@ decl_module! {
});
}

// event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data);
// event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data)
pub fn redeem_kton(origin, proof_record: EthReceiptProof) {
let _relayer = ensure_signed(origin)?;

Expand All @@ -112,7 +114,7 @@ decl_module! {
"Kton For This Proof - ALREADY BEEN REDEEMED",
);

let (darwinia_account, redeemed_amount) = Self::parse_proof(&proof_record, "KtonBurndropTokens")?;
let (darwinia_account, redeemed_amount) = Self::parse_token_redeem_proof(&proof_record, "KtonBurndropTokens")?;
let redeemed_kton = <KtonBalanceOf<T>>::saturated_from(redeemed_amount);
let redeemed_positive_imbalance_kton = T::Kton::deposit_into_existing(&darwinia_account, redeemed_kton)?;

Expand All @@ -125,86 +127,114 @@ decl_module! {
}

// https://github.com/evolutionlandorg/bank
// event Burndrop(uint256 indexed _depositID, address _depositor, uint48 _months, uint48 _startAt, uint64 _unitInterest, uint128 _value, bytes _data);
// event Burndrop(uint256 indexed _depositID, address _depositor, uint48 _months, uint48 _startAt, uint64 _unitInterest, uint128 _value, bytes _data)
// https://ropsten.etherscan.io/tx/0xfd2cac791bb0c0bee7c5711f17ef93401061d314f4eb84e1bc91f32b73134ca1
pub fn redeem_deposit(origin, proof_record: EthReceiptProof) {
let _relayer = ensure_signed(origin)?;

ensure!(!<DepositProofVerified>::exists((proof_record.header_hash, proof_record.index)), "Deposit for this proof has already been redeemed.");

let verified_receipt = T::EthRelay::verify_receipt(&proof_record)?;
ensure!(
!DepositProofVerified::exists((proof_record.header_hash, proof_record.index)),
"Deposit For This Proof - ALREADY BEEN REDEEMED",
);

// event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data);
// https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800
let eth_event = EthEvent {
name: "Burndrop".to_owned(),
inputs: vec![
EthEventParam {name: "_depositID".to_owned(), kind: ParamType::Uint(256), indexed: true,},
EthEventParam {name: "_depositor".to_owned(), kind: ParamType::Address, indexed: false,},
EthEventParam {name: "_months".to_owned(), kind: ParamType::Uint(48), indexed: false,},
EthEventParam {name: "_startAt".to_owned(), kind: ParamType::Uint(48), indexed: false,},
EthEventParam {name: "_unitInterest".to_owned(), kind: ParamType::Uint(64), indexed: false,},
EthEventParam {name: "_value".to_owned(), kind: ParamType::Uint(128), indexed: false,},
EthEventParam {name: "_data".to_owned(), kind: ParamType::Bytes, indexed: false,}
],
anonymous: false,
let result = {
let verified_receipt = T::EthRelay::verify_receipt(&proof_record)?;
let eth_event = EthEvent {
name: "Burndrop".to_owned(),
inputs: vec![
EthEventParam { name: "_depositID".to_owned(), kind: ParamType::Uint(256), indexed: true },
EthEventParam { name: "_depositor".to_owned(), kind: ParamType::Address, indexed: false },
EthEventParam { name: "_months".to_owned(), kind: ParamType::Uint(48), indexed: false },
EthEventParam { name: "_startAt".to_owned(), kind: ParamType::Uint(48), indexed: false },
EthEventParam { name: "_unitInterest".to_owned(), kind: ParamType::Uint(64), indexed: false },
EthEventParam { name: "_value".to_owned(), kind: ParamType::Uint(128), indexed: false },
EthEventParam { name: "_data".to_owned(), kind: ParamType::Bytes, indexed: false }
],
anonymous: false,
};
let log_entry = verified_receipt.
logs
.iter()
.find(|&x| x.address == Self::deposit_redeem_address() && x.topics[0] == eth_event.signature())
.ok_or("Log Entry - NOT FOUND")?;
let log = RawLog {
topics: [log_entry.topics[0],log_entry.topics[1]].to_vec(),
data: log_entry.data.clone()
};

eth_event.parse_log(log).map_err(|_| "Parse Eth Log - FAILED")?
};

let log_entry = verified_receipt.logs.iter().find(
|&x| x.address == Self::deposit_redeem_address()
&& x.topics[0] == eth_event.signature()
).expect("Log Entry Not Found");

let log = RawLog {
topics: [log_entry.topics[0],log_entry.topics[1]].to_vec(),
data: log_entry.data.clone()
let _deposit_id = result
.params[0]
.value
.clone()
.to_uint()
.ok_or("Convert to Int - FAILED")?;
let month = result
.params[2]
.value
.clone()
.to_uint()
.ok_or("Convert to Int - FAILED")?;
// TODO: Check the time unit in seconds or milliseconds
let start_at = result
.params[3]
.value
.clone()
.to_uint()
.ok_or("Convert to Int - FAILED")?;
let redeemed_amount = {
// TODO: div 10**18 and mul 10**9
let amount = result.params[2]
.value
.clone()
.to_uint()
.map(|x| x / U256::from(1_000_000_000u64))
.ok_or("Convert to Int - FAILED")?;

Balance::try_from(amount)?
};
let darwinia_account = {
let raw_sub_key = result.params[3]
.value
.clone()
.to_bytes()
.ok_or("Convert to Bytes - FAILED")?;
let decoded_sub_key = hex::decode(&raw_sub_key).map_err(|_| "Decode Address - FAILED")?;

T::DetermineAccountId::account_id_for(&decoded_sub_key)?
};
let redeemed_ring = <RingBalanceOf<T>>::saturated_from(redeemed_amount);
let redeemed_positive_imbalance_ring = T::Ring::deposit_into_existing(&darwinia_account, redeemed_ring)?;

let result = eth_event.parse_log(log).expect("Parse Eth Log Error");

let _deposit_id : U256 = result.params[0].value.clone().to_uint().expect("Param Convert to Int Failed.");
let month : U256 = result.params[2].value.clone().to_uint().expect("Param Convert to Int Failed.");
T::RingReward::on_unbalanced(redeemed_positive_imbalance_ring);

// TODO: Check the time unit in seconds or milliseconds
let start_at : U256 = result.params[3].value.clone().to_uint().expect("Param Convert to Int Failed.");
// TODO: div 10**18 and mul 10**9
let mut amount: U256 = result.params[5].value.clone().to_uint().expect("Param Convert to Int Failed.");
amount = amount / U256::from(1_000_000_000u64);
let raw_sub_key : Vec<u8> = result.params[6].value.clone().to_bytes().expect("Param Convert to Bytes Failed.");
// TODO: check deposit_id duplication

let decoded_sub_key = hex::decode(&raw_sub_key[..]).expect("Address Hex decode Failed.");
let darwinia_account = T::DetermineAccountId::account_id_for(&decoded_sub_key[..])?;
// TODO: Ignore Unit Interest for now

let redeemed_amount = amount.as_u128().saturated_into();
T::OnDepositRedeem::on_deposit_redeem(
month.saturated_into(),
start_at.saturated_into(),
redeemed_amount,
&darwinia_account,
)?;

DepositProofVerified::insert((proof_record.header_hash, proof_record.index), proof_record);
<RingLocked<T>>::mutate(|l| {
*l = l.saturating_sub(redeemed_amount);
*l = l.saturating_sub(redeemed_ring);
});

<DepositProofVerified>::insert((proof_record.header_hash, proof_record.index), proof_record);

let redeemed_kton = T::Ring::deposit_into_existing(&darwinia_account, redeemed_amount).expect("Deposit into existing failed.");

T::RingReward::on_unbalanced(redeemed_kton);

// TODO: check deposit_id duplication

// TODO: Ignore Unit Interest for now

T::OnDepositRedeem::on_deposit_redeem(month.saturated_into(), start_at.saturated_into(), amount.as_u128(), &darwinia_account)?;
}
}
}

impl<T: Trait> Module<T> {
fn parse_proof(proof: &EthReceiptProof, event_name: &str) -> result::Result<(T::AccountId, Balance), &'static str> {
let verified_receipt = T::EthRelay::verify_receipt(proof)?;

// event RingBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data);
// https://ropsten.etherscan.io/tx/0x81f699c93b00ab0b7db701f87b6f6045c1e0692862fcaaf8f06755abb0536800
// event KtonBurndropTokens(address indexed token, address indexed owner, uint amount, bytes data);
// TODO: address
fn parse_token_redeem_proof(
proof: &EthReceiptProof,
event_name: &str,
) -> result::Result<(T::AccountId, Balance), &'static str> {
let result = {
let verified_receipt = T::EthRelay::verify_receipt(proof)?;
let eth_event = EthEvent {
name: event_name.to_owned(),
inputs: vec![
Expand Down