pub struct Holding {
funds: HashMap<String, u128>,
locked: bool,
}
The code snippet defines a struct called Holding
with two fields: funds
and locked
. The funds
field is of type HashMap<String, u128>
and is used to store the funds of each denomination associated with the holding. The locked
field is of type bool
and indicates whether the holding is locked or not.
pub struct HoldingContract {
holdings: HashMap<String, Holding>,
governance_address: String,
token_service_address: String,
}
The code snippet defines a struct called HoldingContract
with three fields: holdings
, governance_address
, and token_service_address
.
holdings
: AHashMap
that stores the holdings for each address.governance_address
: AString
that represents the governance address.token_service_address
: AString
that represents the token service address.
pub trait IHoldingContract {
// entrypoint
fn hold_fund(&mut self, caller: String, msg: TokenMessage) -> Result<(), ContractError> {
self.ensure_token_service(caller)?;
self.verify_payment(&msg.denom, msg.amount);
let mut holding = self.pop_holding(&msg.receiver_address).unwrap_or_default();
let mut fund = holding.funds.get(&msg.denom).cloned().unwrap_or(0_u128);
fund = fund.checked_add(msg.amount).expect("Addition Overflow");
holding.funds.insert(msg.denom, fund);
Ok(())
}
fn verify_payment(&self, denom: &str, amount: u128) -> bool;
fn ensure_governance(&self, caller: String) -> Result<(), ContractError> {
if self.get_governance() != caller {
return Err(ContractError::Unauthorized);
}
return Ok(());
}
// entrypoint
fn unlock_holding(&mut self, caller: String, address: String) -> Result<(), ContractError> {
self.ensure_governance(caller)?;
if let Some(mut holding) = self.pop_holding(&address) {
holding.locked = false;
self.insert_holding(&address, holding);
}
Ok(())
}
// entrypoint
fn release_holding(&mut self, address: String) -> Result<(), ContractError> {
let holding = self
.pop_holding(&address)
.ok_or(ContractError::NoFundsLocked)?;
if holding.locked {
return Err(ContractError::FundsLocked);
}
holding
.funds
.into_iter()
.map(|f| return self.refund(&address, f.0, f.1))
.collect::<Result<Vec<()>, ContractError>>()?;
Ok(())
}
fn refund(&self, address: &str, denom: String, amount: u128) -> Result<(), ContractError>;
fn pop_holding(&mut self, address: &str) -> Option<Holding>;
fn insert_holding(&mut self, address: &str, holding: Holding) -> Option<Holding>;
fn ensure_token_service(&self, caller: String) -> Result<(), ContractError> {
if self.get_token_service() != caller {
return Err(ContractError::Unauthorized);
}
return Ok(());
}
fn get_token_service(&self) -> String;
fn get_governance(&self) -> String;
}
It takes in a caller
string and a TokenMessage
struct as parameters and returns a Result
with an empty tuple or a ContractError
if an error occurs.
caller
(String): The address of the caller.msg
(TokenMessage): A struct containing information about the token transfer, including the denomination, amount, and receiver address.
- The method first calls the
ensure_token_service
function to check if the caller is authorized to hold funds. - It then calls the
verify_payment
function to validate the payment details. - The method retrieves the holding for the receiver address using the
pop_holding
function. If no holding exists, it creates a new default holding. - It retrieves the current fund amount for the specified denomination from the holding. If no fund exists, it defaults to 0.
- The method adds the amount from the token message to the fund, checking for overflow.
- The updated fund is inserted back into the holding.
- The method returns an empty tuple if all operations are successful.
Result<(), ContractError>
: An empty tuple if the operation is successful or aContractError
if an error occurs.
It takes two parameters, denom
(a string) and amount
(an unsigned 128-bit integer), and returns a boolean value.
denom
: A string representing the denomination of the payment.amount
: An unsigned 128-bit integer representing the amount of the payment.
- The method
verify_payment
takes two parameters,denom
andamount
. - The method calls platform specific method to verify the amount paid on contract call.
- A boolean value indicating whether the payment is verified or not.
The code snippet is a method called ensure_governance
that takes a caller
parameter and returns a Result
indicating whether the caller is authorized or not.
caller
(String): The address of the caller.
- The method compares the result of calling the
get_governance
method onself
(theHoldingContract
instance) with thecaller
parameter. - If the two values are not equal, it returns an
Err
variant of theContractError
enum with the valueUnauthorized
. - If the values are equal, it returns an
Ok
variant with an empty tuple()
.
Result<(), ContractError>
: AnOk
variant with an empty tuple()
if the caller is authorized, or anErr
variant with the valueUnauthorized
if the caller is not authorized.
The code snippet is a method called unlock_holding
that takes in two parameters, caller
and address
, and returns a Result
indicating success or failure. It is responsible for unlocking a holding by setting its locked
flag to false
.
caller
(String): The caller's address.address
(String): The address of the holding to be unlocked.
- The method first calls the
ensure_governance
method to check if the caller has the necessary authorization. - If the caller is authorized, it retrieves the holding associated with the given address using the
pop_holding
method. - If a holding is found, it sets the
locked
flag of the holding tofalse
. - Finally, it inserts the updated holding back into the holdings map using the
insert_holding
method.
Result<(), ContractError>
: ReturnsOk(())
if the holding was successfully unlocked, or an error of typeContractError
if there was an unauthorized access or if no holding was found for the given address.
The code snippet is a method called release_holding
that is part of the IHoldingContract
trait implementation. It releases the funds held in a specific holding by checking if the holding is locked and then refunding the funds to the specified address.It is permissionless so anyone should be able to call it.
self
: a mutable reference to theHoldingContract
instance.address
: aString
representing the address of the holding to be released.
- The method first tries to retrieve the holding associated with the specified address using the
pop_holding
method. If the holding does not exist, it returns anErr
with theNoFundsLocked
error. - If the holding is locked, it returns an
Err
with theFundsLocked
error. - It then iterates over the funds in the holding and calls the
refund
method for each fund, passing the address, denomination, and amount. - If all the refunds are successful, it returns
Ok(())
indicating that the holding has been released.
Result<(), ContractError>
: ReturnsOk(())
if the holding is successfully released, or anErr
with the appropriate error (NoFundsLocked
orFundsLocked
) if the holding does not exist or is locked.
The code snippet is a method called refund
that belongs to the IHoldingContract
trait. It takes in an address, a denomination, and an amount as inputs and returns a Result
with an empty tuple as the success value or a ContractError
as the error value.
address
: A string representing the address to refund the funds to.denom
: A string representing the denomination of the funds.amount
: An unsigned 128-bit integer representing the amount of funds to refund.
- The method
refund
is called with theaddress
,denom
, andamount
as inputs. - Calls platform specific payment method for specified denom and amount.
- The method returns a
Result
with an empty tuple as the success value or aContractError
as the error value.
- If the refund is successful, the method returns
Ok(())
. - If there is an error during the refund process, the method returns a
ContractError
.
The code snippet is a method called pop_holding
that belongs to the HoldingContract
struct. It takes a string address
as input and returns an Option<Holding>
.
address
(string): The address of the holding to be popped.
- The method
pop_holding
is called with anaddress
as input. - The method removes the holding associated with the given
address
from theholdings
HashMap of theHoldingContract
. - The removed holding is returned as an
Option<Holding>
. If a holding with the givenaddress
exists, it is returned asSome(holding)
. If no holding exists with the givenaddress
,None
is returned. - This ensures prevention from
re-entrancy attack
since the holding has been removed from storage before calling payments.
Option<Holding>
: The holding associated with the givenaddress
, if it exists.
The code snippet is a method called insert_holding
that belongs to the HoldingContract
struct. It takes an address and a Holding
object as input and returns an Option<Holding>
.
address
: A string representing the address where the holding will be inserted.holding
: AHolding
object that will be inserted into the contract.
- The method
insert_holding
is called with an address and aHolding
object as input. - The method inserts the
Holding
object into theholdings
HashMap of theHoldingContract
struct using the address as the key. - The method returns an
Option<Holding>
which represents the previous value associated with the address, if any.
- An
Option<Holding>
which represents the previous value associated with the address, if any.
The code snippet is a method called ensure_token_service
that takes a caller
parameter and returns a Result
indicating whether the caller is authorized or not.
caller
(String): The address of the caller.
- The method compares the result of calling the
get_token_service
method onself
(theHoldingContract
instance) with thecaller
parameter. - If the two values are not equal, it returns an
Err
variant of theContractError
enum with the valueUnauthorized
. - If the two values are equal, it returns an
Ok
variant indicating that the caller is authorized.
Result<(), ContractError>
: AnOk
variant if the caller is authorized, or anErr
variant with the valueUnauthorized
if the caller is not authorized.
The code snippet is a method called get_token_service
that belongs to the IHoldingContract
trait.
No inputs are required for this code snippet.
The get_token_service
method returns the token service address stored in the HoldingContract
storage. It does not modify any data or perform any calculations. It simply retrieves and returns the value of the token_service_address
field.
The method returns a String
representing the token service address.
The code snippet is a method called get_governance
that belongs to the IHoldingContract
trait.
No inputs are required for this code snippet.
- The method
get_governance
is called on an instance of theHoldingContract
struct. - The method returns the governance address as a
String
.
- The governance address as a
String
.