Skip to content

Commit

Permalink
Merge branch 'develop' into refactor/lsp7-with-erc725-v8
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ42 committed Sep 3, 2024
2 parents 4e6524a + 0c5f496 commit ee24ca4
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 16 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
fetch-depth: 0

- name: Use Node.js v20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "20.x"
cache: "npm"
Expand All @@ -59,10 +59,10 @@ jobs:
with:
clean: false

- name: Use Node.js '16.15.0'
uses: actions/setup-node@v2
- name: Use Node.js '20.x'
uses: actions/setup-node@v4
with:
node-version: "16.15.0"
node-version: "20.x"
cache: "npm"

- name: 📦 Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
- name: Use Node.js v20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "20.x"
cache: "npm"
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Use Node.js v16
uses: actions/setup-node@v2
- name: Use Node.js v20.x
uses: actions/setup-node@v4
with:
node-version: "16.x"
node-version: "20.x"
cache: "npm"

- name: Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- uses: actions/checkout@v3

- name: Use Node.js v20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "20.x"
cache: "npm"
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/mythx-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Setup Node.js '16.15.0'
uses: actions/setup-node@v2
- name: Setup Node.js '20.x'
uses: actions/setup-node@v4
with:
node-version: "16.15.0"
node-version: "20.x"
cache: "npm"

- name: Set up Python 3.8
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/solc_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Use Node.js '16.15.0'
uses: actions/setup-node@v2
- name: Use Node.js '20.x'
uses: actions/setup-node@v4
with:
node-version: "16.15.0"
node-version: "20.x"
cache: "npm"

- name: 📦 Install dependencies
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodejs 16.19.0
nodejs 20
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { getCreate2Address, concat, keccak256 } from 'ethers';
import { config, ethers } from 'hardhat';
import { DeployFunction } from 'hardhat-deploy/types';

const deployFollowerSystem: DeployFunction = async ({ getNamedAccounts }) => {
const { owner: account } = await getNamedAccounts();
const deployer = await ethers.getSigner(account);
console.log('Deploying with deployer address: ', deployer.address);

const { deterministicDeployment } = config;
const nickFactoryAddress = deterministicDeployment['luksoTestnet'].factory;

console.log('Deploying contract 🆙🔄 using Nick Factory 🧙🏻‍♂️ at address: ', nickFactoryAddress);

// Salt found: 0x7c0acd1428c1a42815d06ceeb50b11fcb9beddb1dcc582ddf5f9ca37979c7e4d with address: 0xf01103E5a9909Fc0DBe8166dA7085e0285daDDcA
// Salt found: 0xc1432fd06941442324a9c2ae23cbb4ac622901a14ee172c419eb9f9e0a324c20 with address: 0xf01103E59c502Eb836A3dfB5f80D101c3FD0f53b

const EXPECTED_ADDRESS = '0xf01103E5a9909Fc0DBe8166dA7085e0285daDDcA';
const STANDARD_SALT = '0x7c0acd1428c1a42815d06ceeb50b11fcb9beddb1dcc582ddf5f9ca37979c7e4d';
const CONTRACT_BYTEODE =
'0x608060405234801561001057600080fd5b50610d6c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c8063645487071161007657806399ec3a421161005b57806399ec3a421461013c578063b2a8d0691461015f578063cf8711c81461017257600080fd5b806364548707146101165780638dd1e47e1461012957600080fd5b8063015a4ead146100a857806330b3a890146100bd5780634dbf27cc146100e35780635a39c581146100f6575b600080fd5b6100bb6100b6366004610a01565b610185565b005b6100d06100cb366004610a01565b610191565b6040519081526020015b60405180910390f35b6100bb6100f1366004610a01565b6101b8565b610109610104366004610a1c565b6101c1565b6040516100da9190610a4f565b6100d0610124366004610a01565b610292565b6100bb610137366004610ae3565b6102b3565b61014f61014a366004610b90565b6102f5565b60405190151581526020016100da565b61010961016d366004610a1c565b61031e565b6100bb610180366004610ae3565b6103e5565b61018e81610423565b50565b6001600160a01b03811660009081526020819052604081206101b2906105d0565b92915050565b61018e816105da565b606060006101cf8484610bd9565b905060008167ffffffffffffffff8111156101ec576101ec610a9c565b604051908082528060200260200182016040528015610215578160200160208202803683370190505b50905060005b828110156102885761024e6102308288610bec565b6001600160a01b038916600090815260016020526040902090610752565b82828151811061026057610260610bff565b6001600160a01b039092166020928302919091019091015261028181610c15565b905061021b565b5095945050505050565b6001600160a01b03811660009081526001602052604081206101b2906105d0565b60005b81518110156102f1576102e18282815181106102d4576102d4610bff565b6020026020010151610423565b6102ea81610c15565b90506102b6565b5050565b6001600160a01b0382166000908152600160205260408120610317908361075e565b9392505050565b6060600061032c8484610bd9565b905060008167ffffffffffffffff81111561034957610349610a9c565b604051908082528060200260200182016040528015610372578160200160208202803683370190505b50905060005b82811015610288576103ab61038d8288610bec565b6001600160a01b038916600090815260208190526040902090610752565b8282815181106103bd576103bd610bff565b6001600160a01b03909216602092830291909101909101526103de81610c15565b9050610378565b60005b81518110156102f15761041382828151811061040657610406610bff565b60200260200101516105da565b61041c81610c15565b90506103e8565b33600090815260016020526040812061043c9083610780565b905080610485576040517fc70bad4e0000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024015b60405180910390fd5b6001600160a01b03821660009081526020819052604090206104a79033610780565b50604080513381526001600160a01b03841660208201527f083700fd0d85112c9d8c5823585c7542e8fadb693c9902e5bc590ab367f7a15e910160405180910390a16105036001600160a01b038316631aed5a8560e21b610795565b156102f1576040516bffffffffffffffffffffffff193360601b1660208201526001600160a01b03831690636bb56a14907f9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f906034015b6040516020818303038152906040526040518363ffffffff1660e01b8152600401610586929190610c52565b6000604051808303816000875af19250505080156105c657506040513d6000823e601f3d908101601f191682016040526105c39190810190610c8c565b60015b156102f157505050565b60006101b2825490565b6001600160a01b038116330361061c576040517fea61954200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526001602052604081206106359083610864565b905080610679576040517f6feacbf60000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161047c565b6001600160a01b038216600090815260208190526040902061069b9033610864565b50604080513381526001600160a01b03841660208201527fbccc71dc7842b86291138666aa18e133ee6d41aa71e6d7c650debad1a0576635910160405180910390a16106f76001600160a01b038316631aed5a8560e21b610795565b156102f1576040516bffffffffffffffffffffffff193360601b1660208201526001600160a01b03831690636bb56a14907f71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a9060340161055a565b60006103178383610879565b6001600160a01b03811660009081526001830160205260408120541515610317565b6000610317836001600160a01b0384166108a3565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d9150600051905082801561084d575060208210155b80156108595750600081115b979650505050505050565b6000610317836001600160a01b038416610996565b600082600001828154811061089057610890610bff565b9060005260206000200154905092915050565b6000818152600183016020526040812054801561098c5760006108c7600183610bd9565b85549091506000906108db90600190610bd9565b90508181146109405760008660000182815481106108fb576108fb610bff565b906000526020600020015490508087600001848154811061091e5761091e610bff565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061095157610951610d20565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506101b2565b60009150506101b2565b60008181526001830160205260408120546109dd575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556101b2565b5060006101b2565b80356001600160a01b03811681146109fc57600080fd5b919050565b600060208284031215610a1357600080fd5b610317826109e5565b600080600060608486031215610a3157600080fd5b610a3a846109e5565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015610a905783516001600160a01b031683529284019291840191600101610a6b565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610adb57610adb610a9c565b604052919050565b60006020808385031215610af657600080fd5b823567ffffffffffffffff80821115610b0e57600080fd5b818501915085601f830112610b2257600080fd5b813581811115610b3457610b34610a9c565b8060051b9150610b45848301610ab2565b8181529183018401918481019088841115610b5f57600080fd5b938501935b83851015610b8457610b75856109e5565b82529385019390850190610b64565b98975050505050505050565b60008060408385031215610ba357600080fd5b610bac836109e5565b9150610bba602084016109e5565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b818103818111156101b2576101b2610bc3565b808201808211156101b2576101b2610bc3565b634e487b7160e01b600052603260045260246000fd5b600060018201610c2757610c27610bc3565b5060010190565b60005b83811015610c49578181015183820152602001610c31565b50506000910152565b8281526040602082015260008251806040840152610c77816060850160208701610c2e565b601f01601f1916919091016060019392505050565b600060208284031215610c9e57600080fd5b815167ffffffffffffffff80821115610cb657600080fd5b818401915084601f830112610cca57600080fd5b815181811115610cdc57610cdc610a9c565b610cef601f8201601f1916602001610ab2565b9150808252856020828501011115610d0657600080fd5b610d17816020840160208601610c2e565b50949350505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d49dd5b2a7c580c2c5c73e52c9cd6bd492943d285801069245b07017db7893bd64736f6c63430008110033';

const preCalculatedAddress = getCreate2Address(
nickFactoryAddress,
STANDARD_SALT,
keccak256(CONTRACT_BYTEODE),
);

if (preCalculatedAddress !== EXPECTED_ADDRESS) {
throw new Error(
`❌ Aborting CREATE2 deployment: Incorrect pre-calculated address with CREATE2. Expected ${EXPECTED_ADDRESS}, got ${preCalculatedAddress}`,
);
} else {
function Create2Address(name, address) {
this.name = name;
this.address = address;
}

console.log(`Pre-calculated address match! 🪄`);
console.table([
new Create2Address('EXPECTED_ADDRESS', EXPECTED_ADDRESS),
new Create2Address('getCreate2Address', preCalculatedAddress),
]);
console.log('✅ Processing with deployment: ');
}

const deploymentTx = {
to: nickFactoryAddress,
data: concat([STANDARD_SALT, CONTRACT_BYTEODE]),
};

const tx = await deployer.sendTransaction(deploymentTx);
console.log('Deployment tx: ', tx);
};

export default deployFollowerSystem;
deployFollowerSystem.tags = ['LSP26FollowerSystem'];
24 changes: 24 additions & 0 deletions packages/lsp26-contracts/contracts/mock/InfiniteLoopURD.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

// interfaces
import {
ILSP1UniversalReceiver
} from "@lukso/lsp1-contracts/contracts/ILSP1UniversalReceiver.sol";

contract InfiniteLoopURD is ILSP1UniversalReceiver {
uint256 public counter;

function supportsInterface(bytes4) external pure returns (bool) {
return true;
}

function universalReceiver(
bytes32,
bytes memory
) external payable returns (bytes memory) {
while (true) {
++counter;
}
}
}
26 changes: 26 additions & 0 deletions packages/lsp26-contracts/contracts/mock/ReturnBomb.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

// interfaces
import {
ILSP1UniversalReceiver
} from "@lukso/lsp1-contracts/contracts/ILSP1UniversalReceiver.sol";

contract ReturnBomb is ILSP1UniversalReceiver {
uint256 public counter;

function supportsInterface(bytes4) external pure returns (bool) {
return true;
}

function universalReceiver(
bytes32,
bytes memory
) external payable returns (bytes memory) {
++counter;
// solhint-disable-next-line no-inline-assembly
assembly {
revert(0, 10000)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;

// interfaces
import {
ILSP1UniversalReceiver
} from "@lukso/lsp1-contracts/contracts/ILSP1UniversalReceiver.sol";

contract SelfDestructOnInterfaceCheck is ILSP1UniversalReceiver {
uint256 public counter;

function supportsInterface(bytes4) external returns (bool) {
selfdestruct(payable(msg.sender));
return true;
}

function universalReceiver(
bytes32,
bytes memory
) external payable returns (bytes memory) {
return "";
}
}
96 changes: 96 additions & 0 deletions packages/lsp26-contracts/tests/LSP26FollowerSystem.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import {
LSP0ERC725Account__factory,
RevertOnFollow__factory,
RevertOnFollow,
ReturnBomb__factory,
ReturnBomb,
SelfDestructOnInterfaceCheck__factory,
SelfDestructOnInterfaceCheck,
InfiniteLoopURD,
InfiniteLoopURD__factory,
} from '../types';

describe('testing `LSP26FollowerSystem`', () => {
Expand Down Expand Up @@ -115,6 +121,96 @@ describe('testing `LSP26FollowerSystem`', () => {
});
});

describe('testing follow/unfollow a contract that self destructs on interface check', async () => {
let selfDestruct: SelfDestructOnInterfaceCheck;

before(async () => {
selfDestruct = await new SelfDestructOnInterfaceCheck__factory(context.owner).deploy();
});

it('should pass following', async () => {
await context.followerSystem.connect(context.owner).follow(await selfDestruct.getAddress());

expect(
await context.followerSystem.isFollowing(
context.owner.address,
await selfDestruct.getAddress(),
),
).to.be.true;
});

it('should pass unfollowing', async () => {
await context.followerSystem.connect(context.owner).unfollow(await selfDestruct.getAddress());

expect(
await context.followerSystem.isFollowing(
context.owner.address,
await selfDestruct.getAddress(),
),
).to.be.false;
});
});

describe('testing follow/unfollow a contract with return bomb', () => {
let returnBomb: ReturnBomb;

before(async () => {
returnBomb = await new ReturnBomb__factory(context.owner).deploy();
});

it('should pass following', async () => {
await context.followerSystem.connect(context.owner).follow(await returnBomb.getAddress());

expect(
await context.followerSystem.isFollowing(
context.owner.address,
await returnBomb.getAddress(),
),
).to.be.true;
});

it('should pass unfollowing', async () => {
await context.followerSystem.connect(context.owner).unfollow(await returnBomb.getAddress());

expect(
await context.followerSystem.isFollowing(
context.owner.address,
await returnBomb.getAddress(),
),
).to.be.false;
});
});

describe('testing follow/unfollow a contract that has an infinite loop in urd', () => {
let infiniteLoop: InfiniteLoopURD;

before(async () => {
infiniteLoop = await new InfiniteLoopURD__factory(context.owner).deploy();
});

it('should pass following', async () => {
await context.followerSystem.connect(context.owner).follow(await infiniteLoop.getAddress());

expect(
await context.followerSystem.isFollowing(
context.owner.address,
await infiniteLoop.getAddress(),
),
).to.be.true;
});

it('should pass unfollowing', async () => {
await context.followerSystem.connect(context.owner).unfollow(await infiniteLoop.getAddress());

expect(
await context.followerSystem.isFollowing(
context.owner.address,
await infiniteLoop.getAddress(),
),
).to.be.false;
});
});

describe.skip('gas tests', () => {
const gasCostResult: {
followingGasCost?: number[];
Expand Down

0 comments on commit ee24ca4

Please sign in to comment.