Skip to content

Commit

Permalink
Merge pull request #78 from Concordium/kb/move-exchange-rates
Browse files Browse the repository at this point in the history
Move `ExchangeRates` from concordium-std
  • Loading branch information
Bargsteen authored Mar 21, 2023
2 parents bd19cee + eeb612e commit b3a04cb
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
40 changes: 40 additions & 0 deletions concordium-contracts-common/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,46 @@ impl Deserial for ExchangeRate {
}
}

impl Serial for ExchangeRates {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> {
self.euro_per_energy.serial(out)?;
self.micro_ccd_per_euro.serial(out)?;
Ok(())
}
}

impl Deserial for ExchangeRates {
fn deserial<R: Read>(source: &mut R) -> ParseResult<Self> {
let bytes: [u8; 32] = source.read_array()?;
let chunks = unsafe { transmute::<[u8; 32], [[u8; 8]; 4]>(bytes) };

let euro_per_energy_numerator = u64::from_le_bytes(chunks[0]);
let euro_per_energy_denominator = u64::from_le_bytes(chunks[1]);
let micro_ccd_per_euro_numerator = u64::from_le_bytes(chunks[2]);
let micro_ccd_per_euro_denominator = u64::from_le_bytes(chunks[3]);

if euro_per_energy_numerator == 0
|| euro_per_energy_denominator == 0
|| micro_ccd_per_euro_numerator == 0
|| micro_ccd_per_euro_denominator == 0
{
return Err(ParseError::default());
}

let euro_per_energy =
ExchangeRate::new_unchecked(euro_per_energy_numerator, euro_per_energy_denominator);
let micro_ccd_per_euro = ExchangeRate::new_unchecked(
micro_ccd_per_euro_numerator,
micro_ccd_per_euro_denominator,
);

Ok(Self {
euro_per_energy,
micro_ccd_per_euro,
})
}
}

impl Serial for ModuleReference {
fn serial<W: Write>(&self, out: &mut W) -> Result<(), W::Err> { out.write_all(self.as_ref()) }
}
Expand Down
31 changes: 31 additions & 0 deletions concordium-contracts-common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,37 @@ impl ExchangeRate {
pub fn denominator(&self) -> u64 { self.denominator }
}

/// The euro/NRG and microCCD/euro exchange rates.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExchangeRates {
/// Euro per NRG exchange rate.
pub euro_per_energy: ExchangeRate,
/// Micro CCD per Euro exchange rate.
pub micro_ccd_per_euro: ExchangeRate,
}

impl ExchangeRates {
/// Convert Euro cent to CCD using the current exchange rate.
/// This will round down to the nearest micro CCD.
pub fn convert_euro_cent_to_amount(&self, euro_cent: u64) -> Amount {
let numerator: u128 = self.micro_ccd_per_euro.numerator().into();
let denominator: u128 = self.micro_ccd_per_euro.denominator().into();
let euro_cent: u128 = euro_cent.into();
let result = numerator * euro_cent / (denominator * 100);
Amount::from_micro_ccd(result as u64)
}

/// Convert CCD to Euro cent using the current exchange rate.
/// This will round down to the nearest Euro cent.
pub fn convert_amount_to_euro_cent(&self, amount: Amount) -> u64 {
let numerator: u128 = self.micro_ccd_per_euro.numerator().into();
let denominator: u128 = self.micro_ccd_per_euro.denominator().into();
let micro_ccd: u128 = amount.micro_ccd().into();
let result = micro_ccd * 100 * denominator / numerator;
result as u64
}
}

/// Chain metadata accessible to both receive and init methods.
#[cfg_attr(
feature = "derive-serde",
Expand Down

0 comments on commit b3a04cb

Please sign in to comment.