Skip to content

Commit 7d626b2

Browse files
committed
getFlowRate and getFlowInfo now also support querying the flowrate from pools to pool members
1 parent aa01376 commit 7d626b2

File tree

2 files changed

+46
-28
lines changed

2 files changed

+46
-28
lines changed

packages/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -122,44 +122,55 @@ library SuperTokenV1Library {
122122
/**
123123
* @dev get flow rate between two accounts for given token
124124
* @param token The token used in flow
125-
* @param sender The sender of the flow
125+
* @param senderOrPool The sender or pool sending the flow
126126
* @param receiverOrPool The receiver or pool receiving or distributing the flow
127-
* @return flowRate The flow rate
128-
* Note: edge case: if a CFA stream is going to a pool, it will return 0.
127+
* @return flowRate The flowrate
128+
* Note: this method auto-detects if it shall look at CFA or GDA flows.
129+
* For GDA flows, either sender or receiver need to be a pool.
129130
*/
130-
function getFlowRate(ISuperToken token, address sender, address receiverOrPool)
131+
function getFlowRate(ISuperToken token, address senderOrPool, address receiverOrPool)
131132
internal view returns(int96 flowRate)
132133
{
134+
// GDA account (distributor) -> pool
133135
if (_isPool(token, receiverOrPool)) {
134136
(, IGeneralDistributionAgreementV1 gda) = _getHostAndGDA(token);
135-
(, flowRate,) = gda.getFlow(token, sender, ISuperfluidPool(receiverOrPool));
137+
(, flowRate,) = gda.getFlow(token, senderOrPool, ISuperfluidPool(receiverOrPool));
138+
// GDA pool -> account (pool member)
139+
} else if (_isPool(token, senderOrPool)) {
140+
flowRate = ISuperfluidPool(senderOrPool).getMemberFlowRate(receiverOrPool);
141+
// CFA account -> account
136142
} else {
137143
(, IConstantFlowAgreementV1 cfa) = _getHostAndCFA(token);
138-
(, flowRate, , ) = cfa.getFlow(token, sender, receiverOrPool);
144+
(, flowRate, , ) = cfa.getFlow(token, senderOrPool, receiverOrPool);
139145
}
140146
}
141147

142148
/**
143-
* @dev get flow info between an account and another account or pool for given token
149+
* @dev get flow info between an account or pool and another account or pool for given token
144150
* @param token The token used in flow
145-
* @param sender The sender of the flow
151+
* @param senderOrPool The sender or pool sending the flow
146152
* @param receiverOrPool The receiver or pool receiving or distributing the flow
147-
* @return lastUpdated Timestamp of flow creation or last flowrate change
148-
* @return flowRate The flow rate
149-
* @return deposit The amount of deposit the flow
150-
* @return owedDeposit The amount of owed deposit of the flow
151-
* Note: edge case: a CFA stream going to a pool will not be "seen".
153+
* @return lastUpdated Timestamp of flow creation or last flowrate change. Not set if the sender is a pool.
154+
* @return flowRate The flow rate.
155+
* @return deposit The amount of deposit of the flow.
156+
* @return owedDeposit The amount of owed deposit of the flow.
152157
*/
153-
function getFlowInfo(ISuperToken token, address sender, address receiverOrPool)
158+
function getFlowInfo(ISuperToken token, address senderOrPool, address receiverOrPool)
154159
internal view
155160
returns(uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
156161
{
162+
// GDA account (distributor) -> pool
157163
if (_isPool(token, receiverOrPool)) {
158164
(, IGeneralDistributionAgreementV1 gda) = _getHostAndGDA(token);
159-
(lastUpdated, flowRate, deposit) = gda.getFlow(token, sender, ISuperfluidPool(receiverOrPool));
165+
(lastUpdated, flowRate, deposit) = gda.getFlow(token, senderOrPool, ISuperfluidPool(receiverOrPool));
166+
// GDA pool -> account (pool member)
167+
} else if (_isPool(token, senderOrPool)) {
168+
flowRate = ISuperfluidPool(senderOrPool).getMemberFlowRate(receiverOrPool);
169+
// deposit and lastUpdated are not set in this case
170+
// CFA account -> account
160171
} else {
161172
(, IConstantFlowAgreementV1 cfa) = _getHostAndCFA(token);
162-
(lastUpdated, flowRate, deposit, owedDeposit) = cfa.getFlow(token, sender, receiverOrPool);
173+
(lastUpdated, flowRate, deposit, owedDeposit) = cfa.getFlow(token, senderOrPool, receiverOrPool);
163174
}
164175
}
165176

packages/ethereum-contracts/test/foundry/apps/SuperTokenV1Library.t.sol

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,11 @@ contract SuperTokenV1LibraryTest is FoundrySuperfluidTester {
288288
ISuperfluidPool pool = superToken.createPool();
289289
pool.updateMemberUnits(bob, 1);
290290

291-
assertEq(superToken.getFlowRate(address(this), address(pool)), 0);
291+
assertEq(superToken.getFlowRate(address(this), address(pool)), 0, "getFlowRate to pool not zero");
292+
assertEq(superToken.getFlowRate(address(pool), bob), 0, "getFlowRate to pool member not zero");
292293
superToken.distributeFlow(pool, DEFAULT_FLOWRATE);
293-
assertEq(superToken.getFlowRate(address(this), address(pool)), DEFAULT_FLOWRATE);
294+
assertEq(superToken.getFlowRate(address(this), address(pool)), DEFAULT_FLOWRATE, "getFlowRate to pool wrong");
295+
assertEq(superToken.getFlowRate(address(pool), bob), DEFAULT_FLOWRATE, "getFlowRate to pool member wrong");
294296
}
295297

296298
function testGetFlowInfoWithCFA() external {
@@ -302,7 +304,6 @@ contract SuperTokenV1LibraryTest is FoundrySuperfluidTester {
302304
assertEq(owedDeposit1, 0);
303305

304306
superToken.flow(bob, DEFAULT_FLOWRATE);
305-
306307
(uint256 lastUpdated2, int96 flowRate2, uint256 deposit2, uint256 owedDeposit2) =
307308
superToken.getFlowInfo(address(this), bob);
308309
assertEq(flowRate2, DEFAULT_FLOWRATE);
@@ -316,20 +317,26 @@ contract SuperTokenV1LibraryTest is FoundrySuperfluidTester {
316317
ISuperfluidPool pool = superToken.createPool();
317318
pool.updateMemberUnits(bob, 1);
318319

319-
(uint256 lastUpdated1, int96 flowRate1, uint256 deposit1, uint256 owedDeposit1) =
320+
(uint256 lastUpdatedToPoolBefore, int96 flowRateToPoolBefore, uint256 depositToPoolBefore, uint256 owedDepositToPoolBefore) =
320321
superToken.getFlowInfo(address(this), address(pool));
321-
assertEq(flowRate1, 0);
322-
assertEq(deposit1, 0);
323-
assertEq(owedDeposit1, 0);
322+
assertEq(flowRateToPoolBefore, 0);
323+
assertEq(depositToPoolBefore, 0);
324+
assertEq(owedDepositToPoolBefore, 0);
325+
326+
(, int96 flowRateToMemberBefore, , ) = superToken.getFlowInfo(address(pool), bob);
327+
assertEq(flowRateToMemberBefore, 0);
324328

325329
superToken.distributeFlow(pool, DEFAULT_FLOWRATE);
326330

327-
(uint256 lastUpdated2, int96 flowRate2, uint256 deposit2, uint256 owedDeposit2) =
331+
(uint256 lastUpdatedToPoolAfter, int96 flowRateToPoolAfter, uint256 depositToPoolAfter, uint256 owedDepositToPoolAfter) =
328332
superToken.getFlowInfo(address(this), address(pool));
329-
assertEq(flowRate2, DEFAULT_FLOWRATE);
330-
assert(deposit2 > 0);
331-
assertEq(owedDeposit2, 0); // GDA doesn't use owed deposits
332-
assert(lastUpdated2 > lastUpdated1);
333+
assertEq(flowRateToPoolAfter, DEFAULT_FLOWRATE);
334+
assert(depositToPoolAfter > 0);
335+
assertEq(owedDepositToPoolAfter, 0); // GDA doesn't use owed deposits
336+
assert(lastUpdatedToPoolAfter > lastUpdatedToPoolBefore);
337+
338+
(, int96 flowRateToMemberAfter, , ) = superToken.getFlowInfo(address(pool), bob);
339+
assertEq(flowRateToMemberAfter, DEFAULT_FLOWRATE);
333340
}
334341

335342
// Make sure actualFlowrate and actualAmount returned by distributeFlow and distribute are always correct.

0 commit comments

Comments
 (0)