From 4e8aa43a900c6fa715c6f64f7c5b6d4d0c041c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernesto=20Garc=C3=ADa?= Date: Wed, 15 Feb 2023 15:21:29 -0600 Subject: [PATCH 1/4] Add publishing integrity check after releasing (#4045) Co-authored-by: Francisco --- .github/workflows/release-cycle.yml | 25 +++++++++++++++++++++ scripts/release/workflow/integrity-check.sh | 20 +++++++++++++++++ scripts/release/workflow/pack.sh | 1 + scripts/release/workflow/publish.sh | 2 +- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 scripts/release/workflow/integrity-check.sh diff --git a/.github/workflows/release-cycle.yml b/.github/workflows/release-cycle.yml index 1831bd5190b..2fd66458d3b 100644 --- a/.github/workflows/release-cycle.yml +++ b/.github/workflows/release-cycle.yml @@ -142,6 +142,11 @@ jobs: run: bash scripts/release/workflow/pack.sh env: PRERELEASE: ${{ needs.state.outputs.is_prerelease }} + - name: Upload tarball artifact + uses: actions/upload-artifact@v3 + with: + name: ${{ github.ref_name }} + path: ${{ steps.pack.outputs.tarball }} - name: Tag run: npx changeset tag - name: Publish @@ -158,6 +163,26 @@ jobs: PRERELEASE: ${{ needs.state.outputs.is_prerelease }} with: script: await require('./scripts/release/workflow/github-release.js')({ github, context }) + outputs: + tarball_name: ${{ steps.pack.outputs.tarball_name }} + + integrity_check: + needs: publish + name: Tarball Integrity Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Download tarball artifact + id: artifact + # Replace with actions/upload-artifact@v3 when + # https://github.com/actions/download-artifact/pull/194 gets released + uses: actions/download-artifact@e9ef242655d12993efdcda9058dee2db83a2cb9b + with: + name: ${{ github.ref_name }} + - name: Check integrity + run: bash scripts/release/workflow/integrity-check.sh + env: + TARBALL: ${{ steps.artifact.outputs.download-path }}/${{ needs.publish.outputs.tarball_name }} merge: needs: state diff --git a/scripts/release/workflow/integrity-check.sh b/scripts/release/workflow/integrity-check.sh new file mode 100644 index 00000000000..86e99f92914 --- /dev/null +++ b/scripts/release/workflow/integrity-check.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -euo pipefail + +CHECKSUMS="$RUNNER_TEMP/checksums.txt" + +# Extract tarball content into a tmp directory +tar xf "$TARBALL" -C "$RUNNER_TEMP" + +# Move to extracted directory +cd "$RUNNER_TEMP/package" + +# Checksum all Solidity files +find . -type f -name "*.sol" | xargs shasum > "$CHECKSUMS" + +# Back to directory with git contents +cd "$GITHUB_WORKSPACE/contracts" + +# Check against tarball contents +shasum -c "$CHECKSUMS" diff --git a/scripts/release/workflow/pack.sh b/scripts/release/workflow/pack.sh index 798417d3d30..ce30712f803 100644 --- a/scripts/release/workflow/pack.sh +++ b/scripts/release/workflow/pack.sh @@ -20,6 +20,7 @@ dist_tag() { cd contracts TARBALL="$(npm pack | tee /dev/stderr | tail -1)" +echo "tarball_name=$TARBALL" >> $GITHUB_OUTPUT echo "tarball=$(pwd)/$TARBALL" >> $GITHUB_OUTPUT echo "tag=$(dist_tag)" >> $GITHUB_OUTPUT cd .. diff --git a/scripts/release/workflow/publish.sh b/scripts/release/workflow/publish.sh index f9e2802d936..41a9975cb55 100644 --- a/scripts/release/workflow/publish.sh +++ b/scripts/release/workflow/publish.sh @@ -15,6 +15,6 @@ delete_tag() { if [ "$TAG" = tmp ]; then delete_tag "$TAG" -elif ["$TAG" = latest ]; then +elif [ "$TAG" = latest ]; then delete_tag next fi From 4ff538af58455987a45243a5ecefca76544969cd Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 15 Feb 2023 19:16:22 -0300 Subject: [PATCH 2/4] Fix flaky timestamp tests (#4046) --- .github/workflows/checks.yml | 1 + test/helpers/governance.js | 15 +++++++++------ test/helpers/time.js | 11 ++++++----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 02664e85c8c..8bb32dcc30c 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -26,6 +26,7 @@ jobs: runs-on: ubuntu-latest env: FORCE_COLOR: 1 + NODE_OPTIONS: --max_old_space_size=4096 GAS: true steps: - uses: actions/checkout@v3 diff --git a/test/helpers/governance.js b/test/helpers/governance.js index ae88e151aae..1ffa086cbd8 100644 --- a/test/helpers/governance.js +++ b/test/helpers/governance.js @@ -115,19 +115,22 @@ class GovernorHelper { : this.governor.castVote(...concatOpts([proposal.id, vote.support], opts)); } - waitForSnapshot(offset = 0) { + async waitForSnapshot(offset = 0) { const proposal = this.currentProposal; - return this.governor.proposalSnapshot(proposal.id).then(timepoint => forward[this.mode](timepoint.addn(offset))); + const timepoint = await this.governor.proposalSnapshot(proposal.id); + return forward[this.mode](timepoint.addn(offset)); } - waitForDeadline(offset = 0) { + async waitForDeadline(offset = 0) { const proposal = this.currentProposal; - return this.governor.proposalDeadline(proposal.id).then(timepoint => forward[this.mode](timepoint.addn(offset))); + const timepoint = await this.governor.proposalDeadline(proposal.id); + return forward[this.mode](timepoint.addn(offset)); } - waitForEta(offset = 0) { + async waitForEta(offset = 0) { const proposal = this.currentProposal; - return this.governor.proposalEta(proposal.id).then(timestamp => forward.timestamp(timestamp.addn(offset))); + const timestamp = await this.governor.proposalEta(proposal.id); + return forward.timestamp(timestamp.addn(offset)); } /** diff --git a/test/helpers/time.js b/test/helpers/time.js index 2e5f6d85a90..30df8dc32ea 100644 --- a/test/helpers/time.js +++ b/test/helpers/time.js @@ -1,16 +1,17 @@ -const { time } = require('@openzeppelin/test-helpers'); +const ozHelpers = require('@openzeppelin/test-helpers'); +const helpers = require('@nomicfoundation/hardhat-network-helpers'); module.exports = { clock: { - blocknumber: () => web3.eth.getBlock('latest').then(block => block.number), - timestamp: () => web3.eth.getBlock('latest').then(block => block.timestamp), + blocknumber: () => helpers.time.latestBlock(), + timestamp: () => helpers.time.latest(), }, clockFromReceipt: { blocknumber: receipt => Promise.resolve(receipt.blockNumber), timestamp: receipt => web3.eth.getBlock(receipt.blockNumber).then(block => block.timestamp), }, forward: { - blocknumber: time.advanceBlockTo, - timestamp: time.increaseTo, + blocknumber: ozHelpers.time.advanceBlockTo, + timestamp: helpers.time.increaseTo, }, }; From 5e76b2622546a2e42e5c19e4ce1a96ee2691c7fe Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Thu, 16 Feb 2023 14:33:56 -0300 Subject: [PATCH 3/4] Add Subgraphs to docs sidebar --- docs/modules/ROOT/nav.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 6604c2de58f..fd206aacd36 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -19,3 +19,5 @@ * xref:crosschain.adoc[Crosschain] * xref:utilities.adoc[Utilities] + +* xref:subgraphs::index.adoc[Subgraphs] From d5d9d4bd3db23444a06bd1a5e2f33fc81e143795 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Fri, 17 Feb 2023 03:35:43 +0100 Subject: [PATCH 4/4] Simplify ERC721Wrapper.depositFor to save gas (#4048) --- .../token/ERC721/extensions/ERC721Wrapper.sol | 23 ++++++------- .../ERC721/extensions/ERC721Wrapper.test.js | 34 +------------------ 2 files changed, 12 insertions(+), 45 deletions(-) diff --git a/contracts/token/ERC721/extensions/ERC721Wrapper.sol b/contracts/token/ERC721/extensions/ERC721Wrapper.sol index f10d555645c..83e59ce88a6 100644 --- a/contracts/token/ERC721/extensions/ERC721Wrapper.sol +++ b/contracts/token/ERC721/extensions/ERC721Wrapper.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.0; import "../ERC721.sol"; -import "../utils/ERC721Holder.sol"; /** * @dev Extension of the ERC721 token contract to support token wrapping. @@ -14,7 +13,7 @@ import "../utils/ERC721Holder.sol"; * * _Available since v4.9.0_ */ -abstract contract ERC721Wrapper is ERC721, ERC721Holder { +abstract contract ERC721Wrapper is ERC721, IERC721Receiver { IERC721 private immutable _underlying; constructor(IERC721 underlyingToken) { @@ -25,11 +24,15 @@ abstract contract ERC721Wrapper is ERC721, ERC721Holder { * @dev Allow a user to deposit underlying tokens and mint the corresponding tokenIds. */ function depositFor(address account, uint256[] memory tokenIds) public virtual returns (bool) { - bytes memory data = abi.encodePacked(account); - uint256 length = tokenIds.length; for (uint256 i = 0; i < length; ++i) { - underlying().safeTransferFrom(_msgSender(), address(this), tokenIds[i], data); + uint256 tokenId = tokenIds[i]; + + // This is an "unsafe" transfer that doesn't call any hook on the receiver. With underlying() being trusted + // (by design of this contract) and no other contracts expected to be called from there, we are safe. + // slither-disable-next-line reentrancy-no-eth + underlying().transferFrom(_msgSender(), address(this), tokenId); + _safeMint(account, tokenId); } return true; @@ -64,16 +67,12 @@ abstract contract ERC721Wrapper is ERC721, ERC721Holder { * for recovering in that scenario. */ function onERC721Received( - address operator, + address, address from, uint256 tokenId, - bytes memory data - ) public override returns (bytes4) { + bytes memory + ) public virtual override returns (bytes4) { require(address(underlying()) == _msgSender(), "ERC721Wrapper: caller is not underlying"); - if (data.length > 0) { - require(data.length == 20 && operator == address(this), "ERC721Wrapper: Invalid data format"); - from = address(bytes20(data)); - } _safeMint(from, tokenId); return IERC721Receiver.onERC721Received.selector; } diff --git a/test/token/ERC721/extensions/ERC721Wrapper.test.js b/test/token/ERC721/extensions/ERC721Wrapper.test.js index 0558dfa37cc..6e46d2e5ab3 100644 --- a/test/token/ERC721/extensions/ERC721Wrapper.test.js +++ b/test/token/ERC721/extensions/ERC721Wrapper.test.js @@ -242,39 +242,7 @@ contract('ERC721Wrapper', function (accounts) { ); }); - describe('when data length is > 0', function () { - it('reverts with arbitrary data', async function () { - await expectRevert( - this.underlying.methods['safeTransferFrom(address,address,uint256,bytes)']( - initialHolder, - this.token.address, - firstTokenId, - '0x0123', - { - from: initialHolder, - }, - ), - 'ERC721Wrapper: Invalid data format', - ); - }); - - it('reverts with correct data from an untrusted operator', async function () { - await expectRevert( - this.underlying.methods['safeTransferFrom(address,address,uint256,bytes)']( - initialHolder, - this.token.address, - firstTokenId, - anotherAccount, - { - from: initialHolder, - }, - ), - 'ERC721Wrapper: Invalid data format', - ); - }); - }); - - it('mints a token to from if no data is specified', async function () { + it('mints a token to from', async function () { const { tx } = await this.underlying.safeTransferFrom(initialHolder, this.token.address, firstTokenId, { from: initialHolder, });