-
Notifications
You must be signed in to change notification settings - Fork 242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ETHEREUM-CONTRACTS] [GDA] Fixes for GDA #1729
Merged
Merged
Changes from 67 commits
Commits
Show all changes
75 commits
Select commit
Hold shift + click to select a range
9bba415
[ETHEREUM-CONTRACTS] BatchLiquidator: don't revert for non-transferra…
d10r 2da9bb9
patch getUnderlyingToken (#1718)
0xdavinchee 7177a50
Bump undici from 5.21.0 to 5.26.3 (#1719)
dependabot[bot] de7df25
add error hashes, use currentContext.timestamp
0xdavinchee 1616671
use getHost.getTimestamp()
0xdavinchee 72f1611
Bump @babel/traverse from 7.21.3 to 7.23.2 (#1723)
dependabot[bot] ffe6790
[SDK-CORE/ METADATA] SDK-Core No Governance Fix + Metadata Types (#1728)
0xdavinchee 1798815
remove tests flakiness
0xdavinchee 99e2d6d
remove forge.sh
0xdavinchee 8ab5829
[SDK-CORE] GoodDollar sdk core fix (#1734)
0xdavinchee e8990d8
[ETHEREUM-CONTRACTS] make deploy script compatible with ethers v6 (#1…
0xdavinchee da9f3e6
update deploy.sh (#1738)
0xdavinchee ddc8213
Bump browserify-sign in /packages/sdk-core/previous-versions-testing …
dependabot[bot] 99f4a68
Bump browserify-sign from 4.2.1 to 4.2.2 (#1739)
dependabot[bot] 7f68614
fix verification script
d10r b50c82f
change GDA forwarder address (needed to redeploy)
d10r 081415f
change GDA forwarder address for polygon-mumbai
d10r 50c3ccf
fix tests to fuzz with different pool configs and fix distributeFlow …
0xdavinchee 5bb4aa2
fix TOB-SUPERFLUID-2: Incorrect event emission in connectPool
0xdavinchee 42e0448
fix TOB-SUPERFLUID-5: Large encoded buffer amount could manipulate pr…
0xdavinchee 66bae97
fix TOB-SUPERFLUID-6: Off-by-one gas left check
0xdavinchee 500e787
fix broken test
0xdavinchee ae6b2f1
wrangle with reducing the code size of GDA...
0xdavinchee 5e1024b
cleanup
0xdavinchee 23acb2c
fix build + tests
0xdavinchee 86d0e27
cleanup
0xdavinchee 761ce76
add update beacon proxy update paths
0xdavinchee a56dc42
fix broken deploy script, add tests, add transfer ownership of beacon…
0xdavinchee 697e497
fix broken deploy script attempt 2
0xdavinchee 3297168
[WORKFLOWS] Use nix in `handler.run-ethereum-contracts-script.yml` (#…
0xdavinchee 4227f0a
[ETHEREUM-CONTRACTS] App credit test (#1743)
0xdavinchee 2295e0f
add cliName (#1748)
0xdavinchee 5389948
doConnect != isConnected fixed
0xdavinchee ce89da0
remove extra whitespace
0xdavinchee e345e10
add assertEq in SFGovII test and import PoolConfig in ISuperfluid for…
0xdavinchee 3516a61
merge conflict resolved
0xdavinchee fffedd0
fix build
0xdavinchee eba67b0
merge metadata changes in
0xdavinchee 10e8f9d
fuzzing fix
0xdavinchee 570812f
EXPECT BREAKAGE IN FUZZ
0xdavinchee 7efa597
fix build but echidna should break
0xdavinchee 27ead42
undo breakage
0xdavinchee fd83f01
fix the test
0xdavinchee c6322e0
bump sdk-core version, fix sdk-core operation functions, fix subgraph…
0xdavinchee e44ec01
fix unit tests
0xdavinchee ce55850
fix again
0xdavinchee 9f51f3e
hot fuzz additions
0xdavinchee bfa428c
[ETHEREUM-CONTRACTS] Fix canary build (#1742)
d10r 8d7d403
distributeFlow: fix order of args to be consistent
d10r 651cbe6
fix build
0xdavinchee 9f32e90
add fix back in
0xdavinchee a98c3c6
[ETHEREUM-CONTRACTS] new resolver and loader, updated and bumped meta…
d10r 9122e24
fix build
d10r 690b599
new resolver and loader, refs #1004
d10r 566fce8
remove getIsListed workaround assuming resolver exists (#1751)
0xdavinchee 37038b4
merge dev
0xdavinchee b892785
fix broken unit test
0xdavinchee 3cb0782
fix gda logic
0xdavinchee a429e11
[ETHEREUM-CONTRACTS] new resolver & loader address for mainnets (#1752)
d10r 4065973
remove unimplemented function from yaml (#1753)
0xdavinchee 7f2e5cf
map the name from subgraph to unknown entity (#1754)
kasparkallas 886c0f1
Merge branch 'dev' into gda-fixes
hellwolf 8516ec6
fix mapping
0xdavinchee a3a5a61
add total units
0xdavinchee 9577da2
missing import
0xdavinchee 655cc5b
missing import pt 2
0xdavinchee e3dcef5
[WORKFLOW] Subgraph deloy all networks (#1760)
mmd-afegbua b182e1d
fix
0xdavinchee e5da4ec
fix mapping (#1758)
0xdavinchee 5f66bbb
added new supported subgraphs (#1761)
mmd-afegbua 941f460
remove duplicate verification
d10r 5526913
subgraph mapping addition
0xdavinchee 1bf8e7c
type fix (#1771)
0xdavinchee abaeb14
readme fix
0xdavinchee a7e370a
Merge branch 'dev' into gda-fixes
0xdavinchee File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,10 +90,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
uint256 private constant _POOL_SUBS_BITMAP_STATE_SLOT_ID = 1; | ||
/// @dev Pool member state slot id starting point for pool connections | ||
uint256 private constant _POOL_CONNECTIONS_DATA_STATE_SLOT_ID_START = 1 << 128; | ||
/// @dev CFAv1 PPP Config Key | ||
bytes32 private constant CFAV1_PPP_CONFIG_KEY = | ||
keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1.PPPConfiguration"); | ||
|
||
/// @dev SuperToken minimum deposit key | ||
bytes32 private constant SUPERTOKEN_MINIMUM_DEPOSIT_KEY = | ||
keccak256("org.superfluid-finance.superfluid.superTokenMinimumDeposit"); | ||
|
||
|
@@ -105,19 +102,21 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
superfluidPoolBeacon = superfluidPoolBeacon_; | ||
} | ||
|
||
function realtimeBalanceVectorAt(ISuperfluidToken token, address account, uint256 time) | ||
function realtimeBalanceOf(ISuperfluidToken token, address account, uint256 time) | ||
public | ||
view | ||
returns (int256 available, int256 fromPools, int256 buffer) | ||
override | ||
returns (int256 rtb, uint256 buf, uint256 owedBuffer) | ||
{ | ||
UniversalIndexData memory universalIndexData = _getUIndexData(abi.encode(token), account); | ||
|
||
if (_isPool(token, account)) { | ||
available = ISuperfluidPool(account).getDisconnectedBalance(uint32(time)); | ||
rtb = ISuperfluidPool(account).getDisconnectedBalance(uint32(time)); | ||
} else { | ||
available = Value.unwrap(_getBasicParticleFromUIndex(universalIndexData).rtb(Time.wrap(uint32(time)))); | ||
rtb = Value.unwrap(_getBasicParticleFromUIndex(universalIndexData).rtb(Time.wrap(uint32(time)))); | ||
} | ||
|
||
int256 fromPools; | ||
{ | ||
(uint32[] memory slotIds, bytes32[] memory pidList) = _listPoolConnectionIds(token, account); | ||
for (uint256 i = 0; i < slotIds.length; ++i) { | ||
|
@@ -126,24 +125,12 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
_getPoolMemberData(token, account, ISuperfluidPool(pool)); | ||
assert(exist); | ||
assert(poolMemberData.pool == pool); | ||
fromPools = fromPools + ISuperfluidPool(pool).getClaimable(account, uint32(time)); | ||
fromPools += ISuperfluidPool(pool).getClaimable(account, uint32(time)); | ||
} | ||
} | ||
rtb += fromPools; | ||
|
||
buffer = universalIndexData.totalBuffer.toInt256(); | ||
} | ||
|
||
function realtimeBalanceOf(ISuperfluidToken token, address account, uint256 time) | ||
public | ||
view | ||
override | ||
returns (int256 rtb, uint256 buf, uint256 owedBuffer) | ||
{ | ||
(int256 available, int256 fromPools, int256 buffer) = realtimeBalanceVectorAt(token, account, time); | ||
rtb = available + fromPools; | ||
|
||
buf = uint256(buffer); // upcasting to uint256 is safe | ||
owedBuffer = 0; | ||
buf = uint256(universalIndexData.totalBuffer.toInt256()); // upcasting to uint256 is safe | ||
} | ||
|
||
/// @dev ISuperAgreement.realtimeBalanceOf implementation | ||
|
@@ -322,10 +309,15 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx); | ||
address msgSender = currentContext.msgSender; | ||
newCtx = ctx; | ||
if (doConnect) { | ||
if (!isMemberConnected(token, address(pool), msgSender)) { | ||
assert(SuperfluidPool(address(pool)).operatorConnectMember(msgSender, true, uint32(block.timestamp))); | ||
bool isConnected = _isMemberConnected(token, address(pool), msgSender); | ||
if (doConnect != isConnected) { | ||
assert( | ||
SuperfluidPool(address(pool)).operatorConnectMember( | ||
msgSender, doConnect, uint32(currentContext.timestamp) | ||
) | ||
); | ||
|
||
if (doConnect) { | ||
uint32 poolSlotID = | ||
_findAndFillPoolConnectionsBitmap(token, msgSender, bytes32(uint256(uint160(address(pool))))); | ||
|
||
|
@@ -336,33 +328,24 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
_getPoolMemberHash(msgSender, pool), | ||
_encodePoolMemberData(PoolMemberData({ poolID: poolSlotID, pool: address(pool) })) | ||
); | ||
} | ||
} else { | ||
if (isMemberConnected(token, address(pool), msgSender)) { | ||
assert(SuperfluidPool(address(pool)).operatorConnectMember(msgSender, false, uint32(block.timestamp))); | ||
} else { | ||
(, PoolMemberData memory poolMemberData) = _getPoolMemberData(token, msgSender, pool); | ||
token.terminateAgreement(_getPoolMemberHash(msgSender, pool), 1); | ||
|
||
_clearPoolConnectionsBitmap(token, msgSender, poolMemberData.poolID); | ||
} | ||
|
||
emit PoolConnectionUpdated(token, pool, msgSender, doConnect, currentContext.userData); | ||
} | ||
|
||
emit PoolConnectionUpdated(token, pool, msgSender, doConnect, currentContext.userData); | ||
} | ||
|
||
/// @inheritdoc IGeneralDistributionAgreementV1 | ||
function isMemberConnected(ISuperfluidToken token, address pool, address member) | ||
public | ||
view | ||
override | ||
returns (bool) | ||
{ | ||
function _isMemberConnected(ISuperfluidToken token, address pool, address member) internal view returns (bool) { | ||
(bool exist,) = _getPoolMemberData(token, member, ISuperfluidPool(pool)); | ||
return exist; | ||
} | ||
|
||
function isMemberConnected(ISuperfluidPool pool, address member) public view override returns (bool) { | ||
return isMemberConnected(pool.superToken(), address(pool), member); | ||
function isMemberConnected(ISuperfluidPool pool, address member) external view override returns (bool) { | ||
return _isMemberConnected(pool.superToken(), address(pool), member); | ||
} | ||
|
||
function appendIndexUpdateByPool(ISuperfluidToken token, BasicParticle memory p, Time t) external returns (bool) { | ||
|
@@ -404,12 +387,15 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
revert GDA_ONLY_SUPER_TOKEN_POOL(); | ||
} | ||
|
||
// you cannot distribute if admin is not equal to the ctx.msgSender | ||
if (!pool.distributionFromAnyAddress()) { | ||
if (pool.admin() != currentContext.msgSender) { | ||
revert GDA_DISTRIBUTE_FROM_ANY_ADDRESS_NOT_ALLOWED(); | ||
} | ||
} | ||
|
||
// the from address must be the same as the ctx.msgSender | ||
// there is no ACL support | ||
if (from != currentContext.msgSender) { | ||
revert GDA_DISTRIBUTE_FOR_OTHERS_NOT_ALLOWED(); | ||
} | ||
|
@@ -467,7 +453,10 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
|
||
newCtx = ctx; | ||
|
||
if (!pool.distributionFromAnyAddress()) { | ||
// we must check if the requestedFlowRate is greater than 0 here | ||
// otherwise we will block liquidators from closing streams in pools | ||
// where the pool config has distributionFromAnyAddress set to false | ||
if (requestedFlowRate > 0 && !pool.distributionFromAnyAddress()) { | ||
if (pool.admin() != flowVars.currentContext.msgSender) { | ||
revert GDA_DISTRIBUTE_FROM_ANY_ADDRESS_NOT_ALLOWED(); | ||
} | ||
|
@@ -479,7 +468,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
address(pool), | ||
flowVars.distributionFlowHash, | ||
FlowRate.wrap(requestedFlowRate), | ||
Time.wrap(uint32(block.timestamp)) | ||
Time.wrap(uint32(flowVars.currentContext.timestamp)) | ||
); | ||
|
||
// handle distribute flow on behalf of someone else | ||
|
@@ -515,14 +504,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
} | ||
|
||
{ | ||
_adjustBuffer( | ||
abi.encode(token), | ||
address(pool), | ||
from, | ||
flowVars.distributionFlowHash, | ||
flowVars.oldFlowRate, | ||
actualFlowRate | ||
); | ||
_adjustBuffer(token, address(pool), from, flowVars.distributionFlowHash, actualFlowRate); | ||
} | ||
|
||
// ensure sender has enough balance to execute transaction | ||
|
@@ -636,7 +618,6 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
_getFlowDistributionData(ISuperfluidToken(data.token), data.distributionFlowHash); | ||
int256 signedSingleDeposit = flowDistributionData.buffer.toInt256(); | ||
|
||
bytes memory liquidationTypeData; | ||
bool isCurrentlyPatricianPeriod; | ||
|
||
{ | ||
|
@@ -652,10 +633,9 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
// critical case | ||
if (totalRewardLeft >= 0) { | ||
int256 rewardAmount = (signedSingleDeposit * totalRewardLeft) / data.signedTotalGDADeposit; | ||
liquidationTypeData = abi.encode(2, isCurrentlyPatricianPeriod ? 0 : 1); | ||
data.token.makeLiquidationPayoutsV2( | ||
data.distributionFlowHash, | ||
liquidationTypeData, | ||
abi.encode(2, isCurrentlyPatricianPeriod ? 0 : 1), | ||
data.liquidator, | ||
isCurrentlyPatricianPeriod, | ||
data.sender, | ||
|
@@ -677,15 +657,9 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
} | ||
} | ||
|
||
function _adjustBuffer( | ||
bytes memory eff, | ||
address pool, | ||
address from, | ||
bytes32 flowHash, | ||
FlowRate, // oldFlowRate, | ||
FlowRate newFlowRate | ||
) internal returns (bytes memory) { | ||
address token = abi.decode(eff, (address)); | ||
function _adjustBuffer(ISuperfluidToken token, address pool, address from, bytes32 flowHash, FlowRate newFlowRate) | ||
internal | ||
{ | ||
// not using oldFlowRate in this model | ||
// surprising effect: reducing flow rate may require more buffer when liquidation_period adjusted upward | ||
ISuperfluidGovernance gov = ISuperfluidGovernance(ISuperfluid(_host).getGovernance()); | ||
|
@@ -718,7 +692,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
ISuperfluidToken(token).updateAgreementData(flowHash, data); | ||
} | ||
|
||
UniversalIndexData memory universalIndexData = _getUIndexData(eff, from); | ||
UniversalIndexData memory universalIndexData = _getUIndexData(abi.encode(token), from); | ||
universalIndexData.totalBuffer = | ||
// new buffer | ||
(universalIndexData.totalBuffer.toInt256() + Value.unwrap(bufferDelta)).toUint256(); | ||
|
@@ -736,8 +710,6 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
universalIndexData.totalBuffer | ||
); | ||
} | ||
|
||
return eff; | ||
} | ||
|
||
// Solvency Related Getters | ||
|
@@ -810,7 +782,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
data = new bytes32[](2); | ||
data[0] = bytes32( | ||
(uint256(int256(FlowRate.unwrap(p.flow_rate()))) << 160) | (uint256(Time.unwrap(p.settled_at())) << 128) | ||
| (buffer << 32) | (isPool_ ? 1 : 0) | ||
| (uint256(buffer.toUint96()) << 32) | (isPool_ ? 1 : 0) | ||
); | ||
data[1] = bytes32(uint256(Value.unwrap(p._settled_value))); | ||
} | ||
|
@@ -823,7 +795,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi | |
data = new bytes32[](2); | ||
data[0] = bytes32( | ||
(uint256(int256(uIndexData.flowRate)) << 160) | (uint256(uIndexData.settledAt) << 128) | ||
| (uint256(uIndexData.totalBuffer) << 32) | (uIndexData.isPool ? 1 : 0) | ||
| (uint256(uIndexData.totalBuffer.toUint96()) << 32) | (uIndexData.isPool ? 1 : 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @hellwolf please take a closer look |
||
); | ||
data[1] = bytes32(uint256(uIndexData.settledValue)); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's improve our echidna fuzzing with better assertions on expected liquidations.