From daa076cb9908cb039abd15d32a9f76b2b5e8fc62 Mon Sep 17 00:00:00 2001 From: "Miao, ZhiCheng" Date: Thu, 18 Apr 2024 01:37:20 +0300 Subject: [PATCH] SemanticMoney: replace inv() with unary '-' operator --- .../src/SemanticMoney.sol | 32 +++++++++---------- .../src/TokenMonad.sol | 2 +- .../test/SemanticMoney.t.sol | 5 +++ .../test/ref-impl/ToySuperToken.t.sol | 28 ++++++++-------- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/packages/solidity-semantic-money/src/SemanticMoney.sol b/packages/solidity-semantic-money/src/SemanticMoney.sol index d7801906ba..c5f50bc0d9 100644 --- a/packages/solidity-semantic-money/src/SemanticMoney.sol +++ b/packages/solidity-semantic-money/src/SemanticMoney.sol @@ -68,9 +68,11 @@ pragma solidity ^0.8.19; */ type Time is uint32; function mt_t_eq(Time a, Time b) pure returns (bool) { return Time.unwrap(a) == Time.unwrap(b); } +function mt_t_neq(Time a, Time b) pure returns (bool) { return Time.unwrap(a) != Time.unwrap(b); } function mt_t_add_t(Time a, Time b) pure returns (Time) { return Time.wrap(Time.unwrap(a) + Time.unwrap(b)); } function mt_t_sub_t(Time a, Time b) pure returns (Time) { return Time.wrap(Time.unwrap(a) - Time.unwrap(b)); } -using { mt_t_eq as ==, mt_t_add_t as +, mt_t_sub_t as - } for Time global; +using { mt_t_eq as ==, mt_t_neq as !=, + mt_t_add_t as +, mt_t_sub_t as - } for Time global; /** * @title Unit value of monetary value represented with 256bits of signed integer. @@ -103,7 +105,8 @@ function mt_r_add_r(FlowRate a, FlowRate b) pure returns (FlowRate) { function mt_r_sub_r(FlowRate a, FlowRate b) pure returns (FlowRate) { return FlowRate.wrap(FlowRate.unwrap(a) - FlowRate.unwrap(b)); } -using { mt_r_eq as ==, mt_r_add_r as +, mt_r_sub_r as - } for FlowRate global; +function mt_r_inv(FlowRate a) pure returns (FlowRate) { return FlowRate.wrap(-FlowRate.unwrap(a)); } +using { mt_r_eq as ==, mt_r_add_r as +, mt_r_sub_r as -, mt_r_inv as - } for FlowRate global; /** * @dev Additional helper functions for the monetary types @@ -113,9 +116,8 @@ using { mt_r_eq as ==, mt_r_add_r as +, mt_r_sub_r as - } for FlowRate global; * Read more at: https://github.com/ethereum/solidity/issues/11969#issuecomment-1448445474 */ library AdditionalMonetaryTypeHelpers { - function inv(Value x) internal pure returns (Value) { - return Value.wrap(-Value.unwrap(x)); - } + // Additional Value operators + // function mul(Value a, Unit b) internal pure returns (Value) { return Value.wrap(Value.unwrap(a) * int256(Unit.unwrap(b))); } @@ -123,10 +125,8 @@ library AdditionalMonetaryTypeHelpers { return Value.wrap(Value.unwrap(a) / int256(Unit.unwrap(b))); } - function inv(FlowRate r) internal pure returns (FlowRate) { - return FlowRate.wrap(-FlowRate.unwrap(r)); - } - + // Additional FlowRate operators + // function mul(FlowRate r, Time t) internal pure returns (Value) { return Value.wrap(int256(FlowRate.unwrap(r)) * int256(uint256(Time.unwrap(t)))); } @@ -404,14 +404,14 @@ library SemanticMoney { function shift2(BasicParticle memory a, BasicParticle memory b, Value x) internal pure returns (BasicParticle memory m, BasicParticle memory n) { - m = a.shift1(x.inv()); + m = a.shift1(-x); n = b.shift1(x); } function flow2(BasicParticle memory a, BasicParticle memory b, FlowRate r, Time t) internal pure returns (BasicParticle memory m, BasicParticle memory n) { - m = a.settle(t).flow1(r.inv()); + m = a.settle(t).flow1(-r); n = b.settle(t).flow1(r); } @@ -422,7 +422,7 @@ library SemanticMoney { BasicParticle memory a1; BasicParticle memory a2; FlowRate r = b.flow_rate(); - (a1, ) = mempty.flow2(b, r.inv(), t); + (a1, ) = mempty.flow2(b, -r, t); (a2, n) = mempty.flow2(b, r + dr, t); m = a.mappend(a1).mappend(a2); } @@ -437,7 +437,7 @@ library SemanticMoney { BasicParticle memory b2; FlowRate r = a.flow_rate(); ( , b1) = a.flow2(mempty, r, t); - (m, b2) = a.flow2(mempty, r.inv() + dr, t); + (m, b2) = a.flow2(mempty, -r + dr, t); n = b.mappend(b1).mappend(b2); } @@ -445,14 +445,14 @@ library SemanticMoney { returns (BasicParticle memory m, PDPoolIndex memory n, Value x1) { (n, x1) = b.shift1(x); - m = a.shift1(x1.inv()); + m = a.shift1(-x1); } function flow2(BasicParticle memory a, PDPoolIndex memory b, FlowRate r, Time t) internal pure returns (BasicParticle memory m, PDPoolIndex memory n, FlowRate r1) { (n, r1) = b.settle(t).flow1(r); - m = a.settle(t).flow1(r1.inv()); + m = a.settle(t).flow1(-r1); } function shift_flow2b(BasicParticle memory a, PDPoolIndex memory b, FlowRate dr, Time t) internal pure @@ -462,7 +462,7 @@ library SemanticMoney { BasicParticle memory a1; BasicParticle memory a2; FlowRate r = b.flow_rate(); - (a1, , ) = mempty.flow2(b, r.inv(), t); + (a1, , ) = mempty.flow2(b, -r, t); (a2, n, r1) = mempty.flow2(b, r + dr, t); m = a.mappend(a1).mappend(a2); } diff --git a/packages/solidity-semantic-money/src/TokenMonad.sol b/packages/solidity-semantic-money/src/TokenMonad.sol index 9b33f08234..a14a09046f 100644 --- a/packages/solidity-semantic-money/src/TokenMonad.sol +++ b/packages/solidity-semantic-money/src/TokenMonad.sol @@ -122,7 +122,7 @@ abstract contract TokenMonad { vars.newAdjustmentFlowRate = FlowRate.wrap(0); } else { // previous adjustment flow still needed - vars.newAdjustmentFlowRate = newActualFlowRate.inv(); + vars.newAdjustmentFlowRate = -newActualFlowRate; newActualFlowRate = FlowRate.wrap(0); } diff --git a/packages/solidity-semantic-money/test/SemanticMoney.t.sol b/packages/solidity-semantic-money/test/SemanticMoney.t.sol index b6eef6f2d7..de8cb83981 100644 --- a/packages/solidity-semantic-money/test/SemanticMoney.t.sol +++ b/packages/solidity-semantic-money/test/SemanticMoney.t.sol @@ -82,6 +82,11 @@ contract SemanticMoneyTest is Test { assertEq(q.mul(u) + e, r, "e1"); } + function test_operators() external { + assertTrue(Time.wrap(0) == Time.wrap(0)); + assertTrue(Time.wrap(0) != Time.wrap(1)); + } + //////////////////////////////////////////////////////////////////////////////// // Particle/Universal Index Properties: Monoidal Laws & Monetary Unit Laws //////////////////////////////////////////////////////////////////////////////// diff --git a/packages/solidity-semantic-money/test/ref-impl/ToySuperToken.t.sol b/packages/solidity-semantic-money/test/ref-impl/ToySuperToken.t.sol index e961085eae..9dc5e85497 100644 --- a/packages/solidity-semantic-money/test/ref-impl/ToySuperToken.t.sol +++ b/packages/solidity-semantic-money/test/ref-impl/ToySuperToken.t.sol @@ -117,7 +117,7 @@ contract ToySuperTokenTest is Test { vm.startPrank(alice); token.flow(alice, bob, FlowId.wrap(0), rr1); vm.stopPrank(); - assertEq(token.getNetFlowRate(alice), rr1.inv(), "e1.1"); + assertEq(token.getNetFlowRate(alice), -rr1, "e1.1"); assertEq(token.getNetFlowRate(bob), rr1, "e1.2"); assertEq(token.getFlowRate(alice, bob, FlowId.wrap(0)), rr1, "e1.3"); @@ -126,7 +126,7 @@ contract ToySuperTokenTest is Test { vm.startPrank(alice); token.flow(alice, bob, FlowId.wrap(0), rr2); vm.stopPrank(); - assertEq(token.getNetFlowRate(alice), rr2.inv(), "e2.1"); + assertEq(token.getNetFlowRate(alice), -rr2, "e2.1"); assertEq(token.getNetFlowRate(bob), rr2, "e2.2"); assertEq(token.getFlowRate(alice, bob, FlowId.wrap(0)), rr2, "e2.3"); @@ -162,7 +162,7 @@ contract ToySuperTokenTest is Test { assertEq(token.getFlowRate(alice, bob, FlowId.wrap(0)), rr1, "e1.1"); assertEq(token.getFlowRate(alice, carol, FlowId.wrap(0)), rr2, "e1.2"); assertEq(token.getFlowRate(bob, carol, FlowId.wrap(0)), FlowRate.wrap(0), "e1.3"); - assertEq(token.getNetFlowRate(alice).inv(), + assertEq(-token.getNetFlowRate(alice), token.getNetFlowRate(bob) + token.getNetFlowRate(carol), "e2"); assertEq(a1 - a2, k2 + (uint256(r1) + uint256(r2)) * uint256(dt1), "e3.1"); assertEq(a1 - a2, k2 + b2 - b1 + c2 - c1, "e3.2"); @@ -197,7 +197,7 @@ contract ToySuperTokenTest is Test { assertEq(token.getFlowRate(bob, carol, FlowId.wrap(0)), rr2, "e1.2"); assertEq(token.getFlowRate(alice, bob, FlowId.wrap(0)), FlowRate.wrap(0), "e1.3"); assertEq(token.getNetFlowRate(alice) + token.getNetFlowRate(bob), - token.getNetFlowRate(carol).inv(), "e2"); + -token.getNetFlowRate(carol), "e2"); assertEq(a1 - a2, k1 + uint256(r1) * uint256(t2), "e3.1"); assertEq(b1 - b2, k2 + uint256(r2) * uint256(t2), "e3.2"); assertEq(a1 - a2 + b1 - b2, k1 + k2 + c2 - c1, "e3.3"); @@ -309,11 +309,11 @@ contract ToySuperTokenTest is Test { emit log_named_int("cnr1", FlowRate.unwrap(cnr1)); assertEq(pdr, pdr1, "e4.1"); - assertEq(anr1, ar.inv() + ajr1, "e4.2"); + assertEq(anr1, -ar + ajr1, "e4.2"); assertEq(pdr, rrr1, "e4.3"); - assertEq(anr1, rrr1.inv() + ajr1, "e4.4"); + assertEq(anr1, -rrr1 + ajr1, "e4.4"); assertEq(bnr1 + cnr1, rrr1, "e4.5"); - assertEq(pnr1, ajr1.inv(), "e4.6"); + assertEq(pnr1, -ajr1, "e4.6"); assertEq(anr1 + bnr1 + cnr1 + pnr1, FlowRate.wrap(0), "e4.7"); } @@ -340,11 +340,11 @@ contract ToySuperTokenTest is Test { emit log_named_int("cnr2", FlowRate.unwrap(cnr2)); assertEq(pdr, pdr2, "e5.1"); - assertEq(ar.inv() + ajr2, anr2, "e5.2"); + assertEq(-ar + ajr2, anr2, "e5.2"); assertEq(pdr, rrr2, "e5.3"); - assertEq(rrr2.inv() + ajr2, anr2, "e5.4"); + assertEq(-rrr2 + ajr2, anr2, "e5.4"); assertEq(bnr2 + cnr2, rrr2, "e5.5"); - assertEq(pnr2, ajr2.inv(), "e5.6"); + assertEq(pnr2, -ajr2, "e5.6"); assertEq(anr2 + bnr2 + cnr2 + pnr2, FlowRate.wrap(0), "e5.7"); } { @@ -424,7 +424,7 @@ contract ToySuperTokenTest is Test { FlowRate pr2 = token.getNetFlowRate(address(pl)); assertEq(pl.getConnectedFlowRate(), rrr, "e4.1"); - assertEq(ar2, rrr.inv(), "e4.2"); + assertEq(ar2, -rrr, "e4.2"); assertEq(br2 + pl.getDisconnectedFlowRate(), rrr, "e4.3"); assertEq(pr2, pl.getDisconnectedFlowRate(), "e4.4"); assertEq(ar2 + br2 + cr2 + pr2, FlowRate.wrap(0), "e4.5"); @@ -505,7 +505,7 @@ contract ToySuperTokenTest is Test { emit log_named_int("pnr4", FlowRate.unwrap(pnr4)); assertEq(pl.getConnectedFlowRate(), rrr, "e3.1"); - assertEq(anr4, rrr.inv(), "e3.2"); + assertEq(anr4, -rrr, "e3.2"); assertEq(bnr4 + pl.getDisconnectedFlowRate(), rrr, "e3.3"); assertEq(pnr4, pl.getDisconnectedFlowRate(), "e3.4"); assertEq(anr4 + bnr4 + pnr4, FlowRate.wrap(0), "e3.5"); @@ -619,8 +619,8 @@ contract ToySuperTokenTest is Test { assertEq(pr2, FlowRate.wrap(0), "e4.5"); assertEq(ar2 + br2 + cr2 + pr2, FlowRate.wrap(0), "e4.6"); assertEq(pdr2, pdr, "e4.7"); - assertEq(ar2.inv(), ar, "e4.8"); - assertEq(br2.inv(), br, "e4.9"); + assertEq(-ar2, ar, "e4.8"); + assertEq(-br2, br, "e4.9"); } {