diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c75d146..e8ad6d14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,9 +68,9 @@ jobs: ALCHEMY_URL: ${{secrets.ALCHEMY_URL}} - name: Delete dbg files run: find ./artifacts/* -name "*.dbg.json" -type f -delete - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: - name: coverage + name: coverage-contracts path: coverage/ slither: @@ -104,9 +104,9 @@ jobs: if: ${{ success() && github.actor != 'dependabot[bot]' }} steps: - uses: actions/checkout@v2 - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v4 with: - name: coverage + name: coverage-contracts path: coverage/ - uses: paambaati/codeclimate-action@v2.7.5 env: diff --git a/addresses/address.json b/addresses/address.json index 3c1190ad..0c2d5e01 100755 --- a/addresses/address.json +++ b/addresses/address.json @@ -320,7 +320,8 @@ "DFRewards": "0xc37F8341Ac6e4a94538302bCd4d49Cf0852D30C0", "DFStrategyV1": "0x3c21a90599b5B7f37014cA5Bf30d3f1b73d7e391", "PredictoorHelper": "0xE9397625Df9B63f0C152f975234b7988b54710B8", - "AccessListFactory": "0x12bB8D85a091A69A07E22E52d4567dBB91568f52" + "AccessListFactory": "0x12bB8D85a091A69A07E22E52d4567dBB91568f52", + "BatchPayments": "0x9497d1d64F2aFeBcd4f9916Eef3d9094E5Df962f" }, "optimism_sepolia": { "chainId": 11155420, diff --git a/contracts/rewards/BatchPayments.sol b/contracts/rewards/BatchPayments.sol new file mode 100644 index 00000000..f6241e98 --- /dev/null +++ b/contracts/rewards/BatchPayments.sol @@ -0,0 +1,38 @@ +// Copyright BigchainDB GmbH and Ocean Protocol contributors +// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) +// Code is Apache-2.0 and docs are CC-BY-4.0 + + +pragma solidity 0.8.12; + + +interface IERC20 { + function transfer(address to, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); +} + + +contract BatchPayments { + function sendEther(address[] memory list, uint256[] memory amounts) external payable { + require(list.length == amounts.length,"Arrays must have same length"); + for (uint256 i = 0; i < list.length; i++) + payable(list[i]).transfer(amounts[i]); + uint256 balance = address(this).balance; + // make sure that we return any excess to the caller + // Later TODO: Check for gas + if (balance > 23000) + payable(msg.sender).call{value: balance}(""); + //payable(msg.sender).transfer(balance); + } + + function sendToken(IERC20 token, address[] memory list, uint256[] memory amounts) external { + require(list.length == amounts.length,"Arrays must have same length"); + uint256 total = 0; + uint256 i; + for (i = 0; i < list.length; i++) + total += amounts[i]; + require(token.transferFrom(msg.sender, address(this), total)); + for (i = 0; i < list.length; i++) + require(token.transfer(list[i], amounts[i])); + } +} \ No newline at end of file diff --git a/scripts/deploy-contracts.js b/scripts/deploy-contracts.js index 4c27cc85..d9d10d78 100644 --- a/scripts/deploy-contracts.js +++ b/scripts/deploy-contracts.js @@ -885,6 +885,23 @@ async function main() { } } + // Batcher + if (logging) console.info("Deploying BatchPayment"); + const BatchPayments = await ethers.getContractFactory( + "BatchPayments", + owner + ); + + const deployBatchPayments = await BatchPayments.connect(owner).deploy(options) + await deployBatchPayments.deployTransaction.wait(); + if (show_verify) { + console.log("\tRun the following to verify on etherscan"); + console.log("\tnpx hardhat verify --network " + networkName + " " + deployBatchPayments.address) + } + addresses.BatchPayments = deployBatchPayments.address; + if (sleepAmount > 0) await sleep(sleepAmount) + + //DF contracts if (shouldDeployDF) { //DFRewards diff --git a/scripts/deploy_batchpayments.js b/scripts/deploy_batchpayments.js new file mode 100644 index 00000000..d9e49da7 --- /dev/null +++ b/scripts/deploy_batchpayments.js @@ -0,0 +1,113 @@ +// We require the Hardhat Runtime Environment explicitly here. This is optional +// but useful for running the script in a standalone fashion through `node