@@ -32,11 +32,167 @@ import { AgreementBase } from "../AgreementBase.sol";
3232import { AgreementLibrary } from "../AgreementLibrary.sol " ;
3333
3434
35+ /*
36+ function getAgreementData(
37+ address agreementClass,
38+ bytes32 id,
39+ uint dataLength
40+ )
41+
42+ function getAgreementStateSlot(
43+ address agreementClass,
44+ address account,
45+ uint256 slotId,
46+ uint dataLength
47+ )
48+
49+ */
50+
3551/// @dev Universal Index state slot id for storing universal index data
3652function _universalIndexStateSlotId () pure returns (uint256 ) {
3753 return 0 ;
3854}
3955
56+ library GeneralDistributionAgreementV1Storage {
57+
58+ uint256 internal constant ACCOUNT_DATA_STATE_SLOT_ID = 0 ;
59+
60+ // # Account Data Operations
61+ //
62+ // Account data includes:
63+ // - Semantic universal index (a basic particle)
64+ // - buffer amount
65+ // - isPool flag
66+ // store buffer (96) and one bit to specify is pool in free
67+ // -------- ------------------ ------------------ ------------------ ------------------
68+ // WORD 1: | flowRate | settledAt | totalBuffer | isPool |
69+ // -------- ------------------ ------------------ ------------------ ------------------
70+ // | 96b | 32b | 96b | 32b |
71+ // -------- ------------------ ------------------ ------------------ ------------------
72+ // WORD 2: | settledValue |
73+ // -------- ------------------ ------------------ ------------------ ------------------
74+ // | 256b |
75+ // -------- ------------------ ------------------ ------------------ ------------------
76+
77+ struct AccountData {
78+ int96 flowRate;
79+ uint32 settledAt;
80+ uint256 totalBuffer;
81+ bool isPool;
82+ int256 settledValue;
83+ }
84+
85+ function encodeUpdatedUniversalIndex (AccountData memory accountData , BasicParticle memory uIndex )
86+ internal
87+ pure
88+ returns (bytes32 [] memory data )
89+ {
90+ data = new bytes32 [](2 );
91+ data[0 ] = bytes32 (
92+ (uint256 (int256 (FlowRate.unwrap (uIndex.flow_rate ()))) << 160 ) |
93+ (uint256 (Time.unwrap (uIndex.settled_at ())) << 128 ) |
94+ (uint256 (SafeCast.toUint96 (accountData.totalBuffer) << 32 )) | (accountData.isPool ? 1 : 0 )
95+ );
96+ data[1 ] = bytes32 (uint256 (Value.unwrap (uIndex._settled_value)));
97+ }
98+
99+ function encodeUpdatedTotalBuffer (AccountData memory accountData , uint256 totalBuffer )
100+ internal
101+ pure
102+ returns (bytes32 [] memory data )
103+ {
104+ data = new bytes32 [](1 );
105+ data[0 ] = bytes32 (
106+ (uint256 (int256 (accountData.flowRate)) << 160 ) |
107+ (uint256 (accountData.settledAt) << 128 ) |
108+ (uint256 (SafeCast.toUint96 (totalBuffer) << 32 )) | (accountData.isPool ? 1 : 0 )
109+ );
110+ }
111+
112+ function decodeAccountData (bytes32 [] memory data )
113+ internal
114+ pure
115+ returns (AccountData memory accountData )
116+ {
117+ uint256 a = uint256 (data[0 ]);
118+ uint256 b = uint256 (data[1 ]);
119+ bool exists = a > 0 || b > 0 ;
120+
121+ if (exists) {
122+ accountData.flowRate = int96 (int256 (a >> 160 ) & int256 (uint256 (type (uint96 ).max)));
123+ accountData.settledAt = uint32 (uint256 (a >> 128 ) & uint256 (type (uint32 ).max));
124+ accountData.totalBuffer = uint256 (a >> 32 ) & uint256 (type (uint96 ).max);
125+ accountData.isPool = ((a << 224 ) >> 224 ) & 1 == 1 ;
126+ accountData.settledValue = int256 (b);
127+ }
128+ }
129+
130+ function getAccountData (bytes memory eff , address owner )
131+ internal
132+ view
133+ returns (AccountData memory accountData )
134+ {
135+ return decodeAccountData (
136+ ISuperfluidToken (abi.decode (eff, (address ))).getAgreementStateSlot (
137+ address (this ), owner, ACCOUNT_DATA_STATE_SLOT_ID, 2
138+ )
139+ );
140+ }
141+
142+ function getUniversalIndexFromAccountData (AccountData memory accountData )
143+ internal
144+ pure
145+ returns (BasicParticle memory uIndex )
146+ {
147+ uIndex._flow_rate = FlowRate.wrap (accountData.flowRate);
148+ uIndex._settled_at = Time.wrap (accountData.settledAt);
149+ uIndex._settled_value = Value.wrap (accountData.settledValue);
150+ }
151+
152+ function setUniversalIndex (bytes memory eff , address owner , BasicParticle memory uIndex )
153+ internal
154+ returns (bytes memory )
155+ {
156+ AccountData memory accountData = getAccountData (eff, owner);
157+
158+ ISuperfluidToken (abi.decode (eff, (address ))).updateAgreementStateSlot (
159+ owner,
160+ ACCOUNT_DATA_STATE_SLOT_ID,
161+ encodeUpdatedUniversalIndex (accountData, uIndex)
162+ );
163+
164+ return eff;
165+ }
166+
167+ function setTotalBuffer (bytes memory eff , address owner , uint256 totalBuffer )
168+ internal
169+ returns (bytes memory )
170+ {
171+ AccountData memory accountData = getAccountData (eff, owner);
172+
173+ ISuperfluidToken (abi.decode (eff, (address ))).updateAgreementStateSlot (
174+ owner,
175+ ACCOUNT_DATA_STATE_SLOT_ID,
176+ encodeUpdatedTotalBuffer (accountData, totalBuffer)
177+ );
178+
179+ return eff;
180+ }
181+
182+ // ..............
183+
184+ /* struct PoolMemberData { */
185+ /* address pool; */
186+ /* uint32 poolID; // the slot id in the pool's subs bitmap */
187+ /* } */
188+
189+ /* struct FlowDistributionData { */
190+ /* uint32 lastUpdated; */
191+ /* int96 flowRate; */
192+ /* uint256 buffer; // stored as uint96 */
193+ /* } */
194+ }
195+
40196/// @dev returns true if the account is a pool
41197function _isPool (
42198 IGeneralDistributionAgreementV1 gda ,
@@ -101,14 +257,6 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
101257 using SafeCast for int256 ;
102258 using SemanticMoney for BasicParticle;
103259
104- struct UniversalIndexData {
105- int96 flowRate;
106- uint32 settledAt;
107- uint256 totalBuffer;
108- bool isPool;
109- int256 settledValue;
110- }
111-
112260 struct PoolMemberData {
113261 address pool;
114262 uint32 poolID; // the slot id in the pool's subs bitmap
@@ -144,12 +292,13 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
144292 override
145293 returns (int256 rtb , uint256 buf , uint256 owedBuffer )
146294 {
147- UniversalIndexData memory universalIndexData = _getUIndexData (abi.encode (token), account);
295+ GeneralDistributionAgreementV1Storage.AccountData memory accountData =
296+ GeneralDistributionAgreementV1Storage.getAccountData (abi.encode (token), account);
148297
149298 if (_isPool (this , token, account)) {
150299 rtb = ISuperfluidPool (account).getDisconnectedBalance (uint32 (time));
151300 } else {
152- rtb = Value.unwrap (_getBasicParticleFromUIndex (universalIndexData ).rtb (Time.wrap (uint32 (time))));
301+ rtb = Value.unwrap (_getBasicParticleFromUIndexData (accountData ).rtb (Time.wrap (uint32 (time))));
153302 }
154303
155304 int256 fromPools;
@@ -166,7 +315,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
166315 }
167316 rtb += fromPools;
168317
169- buf = uint256 (universalIndexData .totalBuffer.toInt256 ()); // upcasting to uint256 is safe
318+ buf = uint256 (accountData .totalBuffer.toInt256 ()); // upcasting to uint256 is safe
170319 owedBuffer = 0 ;
171320 }
172321
@@ -790,112 +939,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
790939 return keccak256 (abi.encode (block .chainid , "poolAdjustmentFlow " , from, to));
791940 }
792941
793- // # Universal Index operations
794- //
795- // Universal Index packing:
796- // store buffer (96) and one bit to specify is pool in free
797- // -------- ------------------ ------------------ ------------------ ------------------
798- // WORD 1: | flowRate | settledAt | totalBuffer | isPool |
799- // -------- ------------------ ------------------ ------------------ ------------------
800- // | 96b | 32b | 96b | 32b |
801- // -------- ------------------ ------------------ ------------------ ------------------
802- // WORD 2: | settledValue |
803- // -------- ------------------ ------------------ ------------------ ------------------
804- // | 256b |
805- // -------- ------------------ ------------------ ------------------ ------------------
806-
807- function _encodeUniversalIndexData (BasicParticle memory p , uint256 buffer , bool isPool_ )
808- internal
809- pure
810- returns (bytes32 [] memory data )
811- {
812- data = new bytes32 [](2 );
813- data[0 ] = bytes32 (
814- (uint256 (int256 (FlowRate.unwrap (p.flow_rate ()))) << 160 ) | (uint256 (Time.unwrap (p.settled_at ())) << 128 )
815- | (uint256 (buffer.toUint96 ()) << 32 ) | (isPool_ ? 1 : 0 )
816- );
817- data[1 ] = bytes32 (uint256 (Value.unwrap (p._settled_value)));
818- }
819-
820- function _encodeUniversalIndexData (UniversalIndexData memory uIndexData )
821- internal
822- pure
823- returns (bytes32 [] memory data )
824- {
825- data = new bytes32 [](2 );
826- data[0 ] = bytes32 (
827- (uint256 (int256 (uIndexData.flowRate)) << 160 ) | (uint256 (uIndexData.settledAt) << 128 )
828- | (uint256 (uIndexData.totalBuffer.toUint96 ()) << 32 ) | (uIndexData.isPool ? 1 : 0 )
829- );
830- data[1 ] = bytes32 (uint256 (uIndexData.settledValue));
831- }
832-
833- function _decodeUniversalIndexData (bytes32 [] memory data )
834- internal
835- pure
836- returns (bool exists , UniversalIndexData memory universalIndexData )
837- {
838- uint256 a = uint256 (data[0 ]);
839- uint256 b = uint256 (data[1 ]);
840-
841- exists = a > 0 || b > 0 ;
842-
843- if (exists) {
844- universalIndexData.flowRate = int96 (int256 (a >> 160 ) & int256 (uint256 (type (uint96 ).max)));
845- universalIndexData.settledAt = uint32 (uint256 (a >> 128 ) & uint256 (type (uint32 ).max));
846- universalIndexData.totalBuffer = uint256 (a >> 32 ) & uint256 (type (uint96 ).max);
847- universalIndexData.isPool = ((a << 224 ) >> 224 ) & 1 == 1 ;
848- universalIndexData.settledValue = int256 (b);
849- }
850- }
851-
852- function _getUIndexData (bytes memory eff , address owner )
853- internal
854- view
855- returns (UniversalIndexData memory universalIndexData )
856- {
857- (, universalIndexData) = _decodeUniversalIndexData (
858- ISuperfluidToken (abi.decode (eff, (address ))).getAgreementStateSlot (
859- address (this ), owner, _universalIndexStateSlotId (), 2
860- )
861- );
862- }
863-
864- function _getBasicParticleFromUIndex (UniversalIndexData memory universalIndexData )
865- internal
866- pure
867- returns (BasicParticle memory particle )
868- {
869- particle._flow_rate = FlowRate.wrap (universalIndexData.flowRate);
870- particle._settled_at = Time.wrap (universalIndexData.settledAt);
871- particle._settled_value = Value.wrap (universalIndexData.settledValue);
872- }
873-
874- // TokenMonad virtual functions
875- function _getUIndex (bytes memory eff , address owner ) internal view override returns (BasicParticle memory uIndex ) {
876- (, UniversalIndexData memory universalIndexData ) = _decodeUniversalIndexData (
877- ISuperfluidToken (abi.decode (eff, (address ))).getAgreementStateSlot (
878- address (this ), owner, _universalIndexStateSlotId (), 2
879- )
880- );
881- uIndex = _getBasicParticleFromUIndex (universalIndexData);
882- }
883-
884- function _setUIndex (bytes memory eff , address owner , BasicParticle memory p )
885- internal
886- override
887- returns (bytes memory )
888- {
889- UniversalIndexData memory universalIndexData = _getUIndexData (eff, owner);
890-
891- ISuperfluidToken (abi.decode (eff, (address ))).updateAgreementStateSlot (
892- owner,
893- _universalIndexStateSlotId (),
894- _encodeUniversalIndexData (p, universalIndexData.totalBuffer, universalIndexData.isPool)
895- );
896-
897- return eff;
898- }
942+ // FIXME: Pool data refactoring
899943
900944 function _getPDPIndex (
901945 bytes memory , // eff,
0 commit comments