Smart Contract

FlowCreditMarketMath

A.6b00ff876c299c61.FlowCreditMarketMath

Valid From

138,858,298

Deployed

1w ago
Feb 16, 2026, 01:15:04 AM UTC

Dependents

0 imports
1access(all) contract FlowCreditMarketMath {
2
3    access(all) let one: UFix128
4    access(all) let zero: UFix128
5    access(self) let ufix64Step: UFix128
6    access(self) let ufix64HalfStep: UFix128
7
8    access(all) let decimals: UInt8
9    access(all) let ufix64Decimals: UInt8
10
11    access(all) enum RoundingMode: UInt8 {
12        access(all) case RoundDown
13        access(all) case RoundUp
14        access(all) case RoundHalfUp
15        access(all) case RoundEven
16    }
17
18    /// Fast exponentiation for UFix128 with a non-negative integer exponent (seconds)
19    /// Uses exponentiation-by-squaring with truncation at each multiply (fixed-point semantics)
20    access(all) view fun powUFix128(_ base: UFix128, _ expSeconds: UFix64): UFix128 {
21        if expSeconds == 0.0 { return self.one }
22        if base == self.one { return self.one }
23        var result: UFix128 = self.one
24        var b: UFix128 = base
25        var e: UFix64 = expSeconds
26        // Floor the seconds to an integer count
27        var remaining: UInt64 = UInt64(e)
28        while remaining > 0 {
29            if remaining % UInt64(2) == UInt64(1) {
30                result = result * b
31            }
32            b = b * b
33            remaining = remaining / UInt64(2)
34        }
35        return result
36    }
37
38
39    access(all) view fun div(_ x: UFix128, _ y: UFix128): UFix128 {
40        pre {
41            y > 0.0 as UFix128: "Division by zero"
42        }
43        return x / y
44    }
45
46    access(all) view fun toUFix128(_ value: UFix64): UFix128 {
47        return UFix128(value)
48    }
49
50    access(all) view fun toUFix64(_ value: UFix128, rounding: RoundingMode): UFix64 {
51        let truncated: UFix64 = UFix64(value)
52        let truncatedAs128: UFix128 = UFix128(truncated)
53        let remainder: UFix128 = value - truncatedAs128
54
55        if remainder == 0.0 as UFix128 {
56            return truncated
57        }
58
59        switch rounding {
60        case self.RoundingMode.RoundDown:
61            return truncated
62        case self.RoundingMode.RoundUp:
63            return self.roundUp(truncated)
64        case self.RoundingMode.RoundHalfUp:
65            return remainder >= self.ufix64HalfStep ? self.roundUp(truncated) : truncated
66        case self.RoundingMode.RoundEven:
67            return self.roundHalfToEven(truncated, remainder)
68        }
69        return truncated
70    }
71
72    access(all) view fun toUFix64Round(_ value: UFix128): UFix64 {
73        return self.toUFix64(value, rounding: self.RoundingMode.RoundHalfUp)
74    }
75
76    access(all) view fun toUFix64RoundDown(_ value: UFix128): UFix64 {
77        return self.toUFix64(value, rounding: self.RoundingMode.RoundDown)
78    }
79
80    access(all) view fun toUFix64RoundUp(_ value: UFix128): UFix64 {
81        return self.toUFix64(value, rounding: self.RoundingMode.RoundUp)
82    }
83
84    access(self) view fun roundUp(_ base: UFix64): UFix64 {
85        let increment: UFix64 = 0.00000001
86        return base >= UFix64.max - increment ? UFix64.max : base + increment
87    }
88
89    access(self) view fun roundHalfToEven(_ base: UFix64, _ remainder: UFix128): UFix64 {
90        if remainder < self.ufix64HalfStep {
91            return base
92        }
93        if remainder > self.ufix64HalfStep {
94            return self.roundUp(base)
95        }
96        let scaled: UFix64 = base * 100_000_000.0
97        let scaledInt: UInt64 = UInt64(scaled)
98        return scaledInt % UInt64(2) == UInt64(1) ? self.roundUp(base) : base
99    }
100
101    init() {
102        self.one = 1.0 as UFix128
103        self.zero = 0.0 as UFix128
104        self.ufix64Step = 0.00000001 as UFix128
105        self.ufix64HalfStep = self.ufix64Step / 2.0 as UFix128
106        self.decimals = 24
107        self.ufix64Decimals = 8
108    }
109}
110