Skip to content

Commit

Permalink
fix ufix64 -> uint256 conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
sisyphusSmiling committed Apr 30, 2024
1 parent 54479d5 commit 2088ab0
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
19 changes: 13 additions & 6 deletions cadence/contracts/bridge/FlowEVMBridgeUtils.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,6 @@ contract FlowEVMBridgeUtils {
message: "Scaled integer value ".concat(value.toString()).concat(" exceeds max UFix64 value")
)


return UFix64(scaledValue) + scaledFractional
}

Expand All @@ -844,16 +843,23 @@ contract FlowEVMBridgeUtils {
let integer = UInt256(value)
var fractional = (value % 1.0) * ufixScale

// Calculate the scale for integer and fractional parts
// Calculate the multiplier for integer and fractional parts
var integerMultiplier: UInt256 = self.pow(base:10, exponent: decimals)
let fractionalMultiplierExp: UInt8 = decimals < 8 ? decimals : decimals - 8
let fractionalMultiplierExp: UInt8 = decimals < 8 ? 0 : decimals - 8
var fractionalMultiplier: UInt256 = self.pow(base:10, exponent: fractionalMultiplierExp)

return integer > 0 ? integer * integerMultiplier + UInt256(fractional) : fractionalMultiplier * UInt256(fractional)
// Scale and sum the parts
return integer * integerMultiplier + UInt256(fractional) * fractionalMultiplier
}

/// Converts a UInt256 fractional value with the given decimal places to a scaled UFix64. Note that UFix64 has
/// decimal precision of 8 places so converted values may lose precision and be rounded down.
///
access(all)
view fun uint256FractionalToScaledUFix64Decimals(value: UInt256, decimals: UInt8): UFix64 {
post {
result < 1.0: "Scaled fractional exceeds 1.0"
}
var fractional = value
// Reduce fractional values with trailing zeros
var e: UInt8 = 0
Expand All @@ -866,17 +872,18 @@ contract FlowEVMBridgeUtils {
}
}

// fractional is too long - since UFix64 has 8 decimal places, truncate and assign the first 8 digits
// fractional is too long - since UFix64 has 8 decimal places, truncate to maintain only the first 8 digis
var fractionalReduction: UInt8 = 0
while fractional > 99999999 {
fractional = fractional / 10
fractionalReduction = fractionalReduction + 1
}

// Scale the fractional part
let fractionalMultiplier = self.ufixPow(base: 0.1, exponent: decimals - e - fractionalReduction)
let scaledFractional = UFix64(fractional) * fractionalMultiplier
assert(scaledFractional < 1.0, message: "Scaled fractional exceeds 1.0")

assert(scaledFractional < 1.0, message: "Scaled fractional exceeds 1.0")
return scaledFractional
}

Expand Down
3 changes: 1 addition & 2 deletions cadence/tests/flow_evm_bridge_utils_tests.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ fun testReducedPrecisionUInt256ToUFix64Succeeds() {
access(all)
fun testReducedPrecisionUFix64ToUInt256Succeeds() {
let uintAmount: UInt256 = 24_244_814_054_591
// let uintAmount: UInt256 = 24_299_405_000_000
let ufixAmount: UFix64 = 24_244_814.05459154

let actualUIntAmount = ufix64ToUInt256(ufixAmount, decimals: 6)
Expand Down Expand Up @@ -200,7 +199,7 @@ access(all)
fun testlargeFractionalUFix64ToUInt256Succeeds() {
let largeFractionalUFixAmount: UFix64 = 1.99785982
let largeFractionalUIntAmount: UInt256 = 1_997_859_820_000_000_000
// let largeFractionalUIntAmount: UInt256 = 1_000_000_000_099_785_982
// let largeFractionalUIntAmount: UInt256 = 1,997,859,820,000,000,000
log("testlargeFractionalUFix64ToUInt256Succeeds")

Expand Down

0 comments on commit 2088ab0

Please sign in to comment.