Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ba1b067
distinguish between unsettled and claimable balance in pools
d10r Jun 26, 2025
f76ce16
add assertions
d10r Jun 26, 2025
62697d9
Merge branch 'dev' into 2025-06-fix-claimable
d10r Jun 30, 2025
ab01e42
Merge branch 'dev' into 2025-06-fix-claimable
d10r Jul 3, 2025
ea53653
merge dev
d10r Jul 15, 2025
9c433c5
use new reader function
d10r Jul 15, 2025
b56c0f3
Merge branch 'dev' into 2025-06-fix-claimable
d10r Jul 16, 2025
d6687ab
small fix
d10r Jul 16, 2025
5dad0c3
updated changelog
d10r Jul 16, 2025
882f654
limit valid input size for _settle()
hellwolf Jul 17, 2025
e27cb41
remove some silly type convrersions
hellwolf Jul 17, 2025
5a0fb64
chore: remove redundant words in comment (#2092)
pavedroad Jul 17, 2025
b856b8a
added GDA function which allows the pool admin to connect pools on be…
d10r Jul 17, 2025
cd864bd
add mechanism for opting out of autoconnect using SimpleACL
d10r Jul 17, 2025
88e17f3
revert forge-std upgrade
d10r Jul 17, 2025
8db285b
simplification
d10r Jul 17, 2025
101bdfc
don't restrict autoconnect to pool admin, more testing
d10r Jul 17, 2025
701ea33
fix stack too deep?
d10r Jul 17, 2025
4dce3b7
fix flag
d10r Jul 17, 2025
5a603b2
more shanghai
d10r Jul 17, 2025
77e3f9d
Merge branch 'dev' into 2025-07-autoconnect
d10r Jul 18, 2025
d3bfd95
updated CHANGELOG
d10r Jul 18, 2025
d6c9135
undo disable test
d10r Jul 18, 2025
2aa5ccd
added tryConnectPoolFor to SuperTokenV1Library
d10r Jul 18, 2025
b4e6342
CFASuperAppBase: disable autoconnect in constructor
d10r Jul 18, 2025
c195923
set admin roles in deploy script
d10r Jul 18, 2025
bd1d158
solidity semantic money to shanghai evm
hellwolf Jul 22, 2025
c76c167
added countUsedSlots to SlotsBitmapLibrary
hellwolf Jul 22, 2025
64484ae
GDAv1: use SlotsBitmapLibrary
hellwolf Jul 22, 2025
d8ea0dc
added some asserts to SlotsBitmapLibraryPropertyTest._listData
hellwolf Jul 22, 2025
79109ec
revert solidity semantic money to paris evm
hellwolf Jul 22, 2025
d578842
fix testTryConnectPoolFor
hellwolf Jul 22, 2025
dff96ab
fix testAutoConnectSlotLimit
hellwolf Jul 22, 2025
c855ecf
update flake inputs
hellwolf Jul 23, 2025
e0ca43f
solc: 0.8.26 -> 0.8.30
hellwolf Jul 23, 2025
4ca4195
Merge branch 'update-solc' into 2025-07-autoconnect
hellwolf Jul 23, 2025
ae36ff0
ethereum-contracts: update CHANGELOG.md
hellwolf Jul 23, 2025
365b087
update more solc_version to 0.8.30
hellwolf Jul 23, 2025
5ec58cd
Merge branch 'update-solc' into 2025-07-autoconnect
hellwolf Jul 23, 2025
7b2e30f
revert the wrong fix
hellwolf Jul 23, 2025
7aef0ee
Merge branch 'dev' into 2025-07-autoconnect
hellwolf Jul 23, 2025
cdf0482
small code refactoring to _setPoolConnection
hellwolf Jul 23, 2025
9b4da71
fix tests
d10r Jul 23, 2025
283402a
fix flaky test
d10r Jul 23, 2025
c5fd4d5
fix scheduler test
d10r Jul 24, 2025
088eba3
renamed to _setPoolConnectionFor
d10r Jul 24, 2025
03b81ba
revert if trying to connect a pool for a pool
d10r Jul 24, 2025
5652c9d
calldata storage location for PoolConfig
d10r Jul 24, 2025
21da9df
squeeze out a few more bytes
d10r Jul 24, 2025
5608475
more contract size margin for GDA
d10r Jul 24, 2025
5a3639d
fix import
d10r Jul 24, 2025
a8264c0
Update VestingSchedulerV2.sol
crStiv Jul 27, 2025
0d29e7a
Update VestingSchedulerV3.sol
crStiv Jul 27, 2025
1588c53
Update FlowScheduler.t.sol
crStiv Jul 27, 2025
7935a0e
Update InstantDistributionAgreementV1-Non-Callback.test.ts
crStiv Jul 27, 2025
027a203
Update FlowSchedulerResolver.t.sol
crStiv Jul 27, 2025
2ab51c9
Update VestingSchedulerV2.t.sol
crStiv Jul 27, 2025
31bf0b3
no calldata magic
d10r Jul 31, 2025
d182827
Merge branch 'dev' into 2025-07-autoconnect
d10r Jul 31, 2025
ce3c48a
forge-std: v1.9.1 -> v1.10.0
hellwolf Aug 6, 2025
47f155e
Merge branch 'typ' into update-forge-std
hellwolf Aug 6, 2025
4eb4dd0
Merge branch 'update-forge-std' into 2025-07-autoconnect
hellwolf Aug 6, 2025
71918b4
fix automation contracts
hellwolf Aug 6, 2025
c6cbeb5
Merge branch 'update-forge-std' into 2025-07-autoconnect
hellwolf Aug 6, 2025
5e4332c
Merge branch 'dev' into 2025-07-autoconnect
hellwolf Aug 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/automation-contracts/autowrap/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ root = '../../../'
libs = ['lib']
src = 'packages/automation-contracts/autowrap'
solc_version = "0.8.23"
evm_version = 'paris'
evm_version = 'shanghai'
optimizer = true
optimizer_runs = 200
remappings = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ contract VestingSchedulerV2 is IVestingSchedulerV2, SuperAppBase {
if (!disableClaimCheck && schedule.claimValidityDate != 0)
revert ScheduleNotClaimed();

// Ensure that that the claming date is after the cliff/flow date and before the claim validity date
// Ensure that the claming date is after the cliff/flow date and before the claim validity date
if (schedule.cliffAndFlowDate > block.timestamp ||
_lteDateToExecuteCliffAndFlow(schedule) < block.timestamp)
revert TimeWindowInvalid();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ contract VestingSchedulerV3 is IVestingSchedulerV3, IRelayRecipient {
revert ScheduleNotClaimed();
}

// Ensure that that the claming date is after the cliff/flow date and before the claim validity date
// Ensure that the claming date is after the cliff/flow date and before the claim validity date
if (schedule.cliffAndFlowDate > block.timestamp || _lteDateToExecuteCliffAndFlow(schedule) < block.timestamp) {
revert TimeWindowInvalid();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/automation-contracts/scheduler/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ root = '../../../'
libs = ['lib']
src = 'packages/automation-contracts/scheduler'
solc_version = "0.8.23"
evm_version = 'paris'
evm_version = 'shanghai'
optimizer = true
optimizer_runs = 200
remappings = [
Expand Down
3 changes: 3 additions & 0 deletions packages/ethereum-contracts/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- `GDAv1StorageReader` contains getters reading agreement data from the token contract, allowing contracts to get this data without making a call to the GDA contract.
- `GDAv1StorageWriter` contains functions for writing agreement data to the token contract. This can only be used by the GDA contract itself.

### Fixed
- `ISuperfluidPool`: `getClaimable` and `getClaimableNow` could previously return non-zero values for connected pools, which was inconsistent with what `claimAll` would actually do in this situation (claim nothing).

### Breaking
- PoolMemberNFT pruning: `IPoolMemberNFT` and `PoolMemberNFT` removed, `POOL_MEMBER_NFT()` removed from `ISuperToken`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.23;

import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";

import { ISuperfluid, ISuperfluidGovernance } from "../../interfaces/superfluid/ISuperfluid.sol";
import { ISuperfluid, ISuperfluidGovernance, IAccessControl } from "../../interfaces/superfluid/ISuperfluid.sol";
import {
BasicParticle,
PDPoolIndex,
Expand Down Expand Up @@ -48,6 +48,12 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi

address public constant SUPERFLUID_POOL_DEPLOYER_ADDRESS = address(SuperfluidPoolDeployerLibrary);

// @dev The max number of slots which can be used for connecting pools on behalf of a member (per token)
uint32 public constant MAX_POOL_AUTO_CONNECT_SLOTS = 4;

bytes32 constant public ACL_POOL_CONNECT_EXCLUSIVE_ROLE = keccak256("ACL_POOL_CONNECT_EXCLUSIVE_ROLE");
bytes32 constant public ACL_POOL_CONNECT_EXCLUSIVE_ROLE_ADMIN = keccak256("ACL_POOL_CONNECT_EXCLUSIVE_ROLE_ADMIN");

/// @dev Pool member state slot id for storing subs bitmap
uint256 private constant _POOL_SUBS_BITMAP_STATE_SLOT_ID = 1;
/// @dev Pool member state slot id starting point for pool connections
Expand Down Expand Up @@ -89,7 +95,7 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
for (uint256 i = 0; i < slotIds.length; ++i) {
address pool = address(uint160(uint256(pidList[i])));
_assertPoolConnectivity(token, account, ISuperfluidPool(pool));
totalConnectedFromPools += ISuperfluidPool(pool).getClaimable(account, uint32(time));
totalConnectedFromPools += SuperfluidPool(pool).getUnsettledValue(account, uint32(time));
}
}
rtb += totalConnectedFromPools;
Expand Down Expand Up @@ -305,49 +311,100 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi
pool.claimAll(memberAddress);
}

// @note setPoolConnection function naming
function connectPool(ISuperfluidPool pool, bool doConnect, bytes calldata ctx)
public
returns (bytes memory newCtx)
/// @inheritdoc IGeneralDistributionAgreementV1
function connectPool(ISuperfluidPool pool, bytes calldata ctx) external override returns (bytes memory newCtx) {
newCtx = ctx;
_setPoolConnection(pool, address(0), true, false, ctx);
}

/// @inheritdoc IGeneralDistributionAgreementV1
function tryConnectPoolFor(ISuperfluidPool pool, address memberAddr, bytes calldata ctx)
external
override
returns (bool success, bytes memory newCtx)
{
newCtx = ctx;

// check if the member has opted out of autoconnect
IAccessControl simpleACL = ISuperfluid(_host).getSimpleACL();
if (simpleACL.hasRole(ACL_POOL_CONNECT_EXCLUSIVE_ROLE, memberAddr)) {
success = false;
} else {
success = _setPoolConnection(pool, memberAddr, true, true, ctx);
}
}

function setConnectPermission(bool allow) external override {
IAccessControl simpleACL = ISuperfluid(_host).getSimpleACL();
if (!allow) {
simpleACL.grantRole(ACL_POOL_CONNECT_EXCLUSIVE_ROLE, msg.sender);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

who is the admins of simpleACL??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still the GH agent, but after deploying this it should be handed over to SF gov or SF gov owner.

} else {
simpleACL.revokeRole(ACL_POOL_CONNECT_EXCLUSIVE_ROLE, msg.sender);
}
}

/// @inheritdoc IGeneralDistributionAgreementV1
function disconnectPool(ISuperfluidPool pool, bytes calldata ctx) external override returns (bytes memory newCtx) {
newCtx = ctx;
_setPoolConnection(pool, address(0), false, true /* ignored */, ctx);
}

// @note memberAddr has override semantics - if set to address(0), it will be set to the msgSender
function _setPoolConnection(
ISuperfluidPool pool,
address memberAddr,
bool doConnect,
bool onlyAutoConnectSlots,
bytes memory ctx
)
internal
returns (bool success)
{
ISuperfluidToken token = pool.superToken();
ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);
address msgSender = currentContext.msgSender;
newCtx = ctx;
bool isConnected = token.isPoolMemberConnected(this, pool, msgSender);
if (doConnect != isConnected) {
assert(
SuperfluidPool(address(pool)).operatorConnectMember(
msgSender, doConnect, uint32(currentContext.timestamp)
)
);

if (memberAddr == address(0)) {
memberAddr = currentContext.msgSender;
}

bool isConnected = token.isPoolMemberConnected(this, pool, memberAddr);

if (doConnect != isConnected) {
if (doConnect) {
uint32 poolSlotId =
_findAndFillPoolConnectionsBitmap(token, msgSender, bytes32(uint256(uint160(address(pool)))));
if (onlyAutoConnectSlots) {
// check if we're below the slot limit for autoconnect
(uint32[] memory slotIds, ) = SlotsBitmapLibrary.listData(
token, memberAddr, _POOL_SUBS_BITMAP_STATE_SLOT_ID, _POOL_CONNECTIONS_DATA_STATE_SLOT_ID_START
);
if (slotIds.length >= MAX_POOL_AUTO_CONNECT_SLOTS) {
return false;
}
}

uint32 poolSlotId = _findAndFillPoolConnectionsBitmap(
token, memberAddr, bytes32(uint256(uint160(address(pool))))
);

token.createPoolConnectivity
(msgSender, GDAv1StorageLib.PoolConnectivity({ slotId: poolSlotId, pool: pool }));
(memberAddr, GDAv1StorageLib.PoolConnectivity({ slotId: poolSlotId, pool: pool }));
} else {
(, GDAv1StorageLib.PoolConnectivity memory poolConnectivity) =
token.getPoolConnectivity(this, msgSender, pool);
token.deletePoolConnectivity(msgSender, pool);
token.getPoolConnectivity(this, memberAddr, pool);
token.deletePoolConnectivity(memberAddr, pool);

_clearPoolConnectionsBitmap(token, msgSender, poolConnectivity.slotId);
_clearPoolConnectionsBitmap(token, memberAddr, poolConnectivity.slotId);
}

emit PoolConnectionUpdated(token, pool, msgSender, doConnect, currentContext.userData);
}
}
assert(
SuperfluidPool(address(pool)).operatorConnectMember(
memberAddr, doConnect, uint32(currentContext.timestamp)
)
);

/// @inheritdoc IGeneralDistributionAgreementV1
function connectPool(ISuperfluidPool pool, bytes calldata ctx) external override returns (bytes memory newCtx) {
return connectPool(pool, true, ctx);
}
emit PoolConnectionUpdated(token, pool, memberAddr, doConnect, currentContext.userData);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without adding anything, is there an easy way to know if the connection was an "auto-connect" from event logs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be an issue. An option is to supplement with a new event type.

}

/// @inheritdoc IGeneralDistributionAgreementV1
function disconnectPool(ISuperfluidPool pool, bytes calldata ctx) external override returns (bytes memory newCtx) {
return connectPool(pool, false, ctx);
return true;
}

/// @inheritdoc IGeneralDistributionAgreementV1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
Value.unwrap(
// PDPoolMemberMU(poolIndex, memberData)
PDPoolMemberMU(poolIndexDataToPDPoolIndex(_index), _memberDataToPDPoolMember(memberData)).settle(
Time.wrap(uint32(block.timestamp))
Time.wrap(SafeCast.toUint32(block.timestamp))
).m._settled_value
)
);
Expand Down Expand Up @@ -370,17 +370,14 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
returns (int256 claimableBalance, uint256 timestamp)
{
timestamp = ISuperfluid(superToken.getHost()).getNow();
return (getClaimable(memberAddr, uint32(timestamp)), timestamp);
return (getClaimable(memberAddr, SafeCast.toUint32(timestamp)), timestamp);
}

/// @inheritdoc ISuperfluidPool
function getClaimable(address memberAddr, uint32 time) public view override returns (int256) {
Time t = Time.wrap(time);
PDPoolIndex memory pdPoolIndex = poolIndexDataToPDPoolIndex(_index);
PDPoolMember memory pdPoolMember = _memberDataToPDPoolMember(_membersData[memberAddr]);
return Value.unwrap(
PDPoolMemberMU(pdPoolIndex, pdPoolMember).rtb(t) - Value.wrap(_membersData[memberAddr].claimedValue)
);
return superToken.isPoolMemberConnected(GDA, this, memberAddr)
? int256(0)
: getUnsettledValue(memberAddr, time);
}

/// @inheritdoc ISuperfluidPool
Expand Down Expand Up @@ -430,7 +427,7 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
if (superToken.isPool(GDA, memberAddr)) revert SUPERFLUID_POOL_NO_POOL_MEMBERS();
if (memberAddr == address(0)) revert SUPERFLUID_POOL_NO_ZERO_ADDRESS();

uint32 time = uint32(ISuperfluid(superToken.getHost()).getNow());
uint32 time = SafeCast.toUint32(ISuperfluid(superToken.getHost()).getNow());
Time t = Time.wrap(time);
Unit wrappedUnits = toSemanticMoneyUnit(newUnits);

Expand All @@ -443,7 +440,7 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
PDPoolMemberMU memory mu = PDPoolMemberMU(pdPoolIndex, pdPoolMember);

// update pool's disconnected units
if (!superToken.isPoolMemberConnected(GDA, ISuperfluidPool(address(this)), memberAddr)) {
if (!superToken.isPoolMemberConnected(GDA, this, memberAddr)) {
_shiftDisconnectedUnits(wrappedUnits - mu.m.owned_units, Value.wrap(0), t);
}

Expand All @@ -459,11 +456,26 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
emit MemberUnitsUpdated(superToken, memberAddr, oldUnits, newUnits);
}

function _claimAll(address memberAddr, uint32 time) internal returns (int256 amount) {
amount = getClaimable(memberAddr, time);
assert(GDA.poolSettleClaim(superToken, memberAddr, (amount)));
function _settle(address memberAddr, uint32 time) internal returns (int256 amount) {
amount = getUnsettledValue(memberAddr, time);
assert(GDA.poolSettleClaim(superToken, memberAddr, amount));
_membersData[memberAddr].claimedValue += amount;
}

function getUnsettledValue(address memberAddr, uint32 time) public view returns (int256) {
Time t = Time.wrap(time);
PDPoolIndex memory pdPoolIndex = poolIndexDataToPDPoolIndex(_index);
PDPoolMember memory pdPoolMember = _memberDataToPDPoolMember(_membersData[memberAddr]);
return Value.unwrap(
PDPoolMemberMU(pdPoolIndex, pdPoolMember).rtb(t) - Value.wrap(_membersData[memberAddr].claimedValue)
);
}

function _claimAll(address memberAddr, uint32 time) internal returns (int256 amount) {
// For connected pool, claimable amount is zero; hence, we skip.
if (!superToken.isPoolMemberConnected(GDA, this, memberAddr)) {
amount = _settle(memberAddr, time);
}
emit DistributionClaimed(superToken, memberAddr, amount, _membersData[memberAddr].claimedValue);
}

Expand All @@ -475,7 +487,7 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {
/// @inheritdoc ISuperfluidPool
function claimAll(address memberAddr) public returns (bool) {
bool isConnected = superToken.isPoolMemberConnected(GDA, this, memberAddr);
uint32 time = uint32(ISuperfluid(superToken.getHost()).getNow());
uint32 time = SafeCast.toUint32(ISuperfluid(superToken.getHost()).getNow());
int256 claimedAmount = _claimAll(memberAddr, time);
if (!isConnected) {
_shiftDisconnectedUnits(Unit.wrap(0), Value.wrap(claimedAmount), Time.wrap(time));
Expand All @@ -492,10 +504,10 @@ contract SuperfluidPool is ISuperfluidPool, BeaconProxiable {

// WARNING for operators: it is undefined behavior if member is already connected or disconnected
function operatorConnectMember(address memberAddr, bool doConnect, uint32 time) external onlyGDA returns (bool) {
int256 claimedAmount = _claimAll(memberAddr, time);
int256 settleAmount = _settle(memberAddr, time);
int128 units = uint256(_getUnits(memberAddr)).toInt256().toInt128();
if (doConnect) {
_shiftDisconnectedUnits(Unit.wrap(-units), Value.wrap(claimedAmount), Time.wrap(time));
_shiftDisconnectedUnits(Unit.wrap(-units), Value.wrap(settleAmount), Time.wrap(time));
} else {
_shiftDisconnectedUnits(Unit.wrap(units), Value.wrap(0), Time.wrap(time));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,23 @@ abstract contract IGeneralDistributionAgreementV1 is ISuperAgreement {
/// @return newCtx the new context bytes
function connectPool(ISuperfluidPool pool, bytes calldata ctx) external virtual returns (bytes memory newCtx);

/// @notice Allows the pool admin to connect a member to the pool if autoconnect slots are available.
/// "autoconnect slots" are a subset of the slots available to pool members themselves.
/// @param pool The pool address
/// @param memberAddr The member address
/// @param ctx Context bytes
/// @return success true if the member was (or remained) connected, false otherwise
/// @return newCtx the new context bytes
function tryConnectPoolFor(ISuperfluidPool pool, address memberAddr, bytes calldata ctx)
external
virtual
returns (bool success, bytes memory newCtx);

/// @notice Lets accounts deny or allow 3rd parties to connect them to pools.
/// By default, this permission is given (except by accounts which are Super Apps).
/// @param allow true to allow, false to deny
function setConnectPermission(bool allow) external virtual;

/// @notice Disconnects `msg.sender` from `pool`.
/// @dev This is used to disconnect a pool from the GDA.
/// @param pool The pool address
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {ISuperfluidToken} from "../interfaces/superfluid/ISuperfluidToken.sol";
* - A data slot can be enabled or disabled with the help of bitmap.
* - MAX_NUM_SLOTS is 256 in this implementation (using one uint256)
* - Superfluid token storage usage:
* - getAgreementStateSlot(bitmapStateSlotId) stores the bitmap of enabled data slots
* - getAgreementStateSlot(dataStateSlotIDStart + stotId) stores the data of the slot
* - updateAgreementStateSlot(bitmapStateSlotId) stores the bitmap of enabled data slots
* - updateAgreementStateSlot(dataStateSlotIDStart + stotId) stores the data of the slot
*/
library SlotsBitmapLibrary {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ contract SuperfluidFrameworkDeploymentSteps {
gdaV1Logic.superfluidPoolBeacon().upgradeTo(address(superfluidPoolLogic));
gdaV1Logic.superfluidPoolBeacon().transferOwnership(address(host));
}

SimpleACL(address(host.getSimpleACL())).setRoleAdmin(
gdaV1.ACL_POOL_CONNECT_EXCLUSIVE_ROLE(),
gdaV1.ACL_POOL_CONNECT_EXCLUSIVE_ROLE_ADMIN()
);
SimpleACL(address(host.getSimpleACL())).grantRole(
gdaV1.ACL_POOL_CONNECT_EXCLUSIVE_ROLE_ADMIN(),
address(gdaV1)
);
} else if (step == 3) {// PERIPHERAL CONTRACTS: NFT Proxy and Logic
{
poolAdminNFT = PoolAdminNFT(address(ProxyDeployerLibrary.deployUUPSProxy()));
Expand Down
2 changes: 1 addition & 1 deletion packages/ethereum-contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ignored_error_codes = [
1699 # assembly { selfdestruct } in contracts/mocks/SuperfluidDestructorMock.sol
]
# keep in sync with truffle-config.js
evm_version = 'paris'
evm_version = 'shanghai'
optimizer = true
optimizer_runs = 200
remappings = [
Expand Down
2 changes: 1 addition & 1 deletion packages/ethereum-contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const config: HardhatUserConfig = {
enabled: true,
runs: 200,
},
evmVersion: "paris",
evmVersion: "shanghai",
},
},
paths: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ module.exports = eval(`(${S.toString()})({skipArgv: true})`)(async function (
const poolMemberNFTPAddr = await superTokenLogic.POOL_MEMBER_NFT();
let poolMemberNFTLAddr = ZERO_ADDRESS;
if (poolMemberNFTPAddr !== ZERO_ADDRESS) {
const poolMemberNFTContract = await PoolMemberNFT.at(poolMemberNFTPAddr);
const poolMemberNFTContract = await UUPSProxiable.at(poolMemberNFTPAddr);
poolMemberNFTLAddr = await poolMemberNFTContract.getCodeAddress();
}

Expand Down
Loading
Loading