From 07dc68b810d0e872ef4624c9c2e92d436af42fd9 Mon Sep 17 00:00:00 2001 From: ironbeer <7997273+ironbeer@users.noreply.github.com> Date: Fri, 10 Mar 2023 19:27:24 +0900 Subject: [PATCH 1/2] Updated artifacts --- .../OASMultiTransfer.json | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 artifacts/contracts/util/OASMultiTransfer.sol/OASMultiTransfer.json diff --git a/artifacts/contracts/util/OASMultiTransfer.sol/OASMultiTransfer.json b/artifacts/contracts/util/OASMultiTransfer.sol/OASMultiTransfer.json new file mode 100644 index 0000000..babf3b8 --- /dev/null +++ b/artifacts/contracts/util/OASMultiTransfer.sol/OASMultiTransfer.json @@ -0,0 +1,50 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "OASMultiTransfer", + "sourceName": "contracts/util/OASMultiTransfer.sol", + "abi": [ + { + "inputs": [], + "name": "InvalidArgument", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "tos", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "transfer", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610467806100206000396000f3fe60806040526004361061001e5760003560e01c8063ffc3a76914610023575b600080fd5b610036610031366004610323565b610038565b005b805182511461005a5760405163a9cb9e0d60e01b815260040160405180910390fd5b60005b82518110156101cd5760006001600160a01b0316838281518110610083576100836103f2565b60200260200101516001600160a01b0316141561009f576101bb565b8181815181106100b1576100b16103f2565b6020026020010151600014156100c6576101bb565b60008382815181106100da576100da6103f2565b60200260200101516001600160a01b03168383815181106100fd576100fd6103f2565b602002602001015160405160006040518083038185875af1925050503d8060008114610145576040519150601f19603f3d011682016040523d82523d6000602084013e61014a565b606091505b50509050806101b957838281518110610165576101656103f2565b602002602001015183838151811061017f5761017f6103f2565b6020908102919091010151604051630e21dcbb60e11b81526001600160a01b03909216600483015260248201526044015b60405180910390fd5b505b806101c581610408565b91505061005d565b50476101d7575050565b604051600090339047908381818185875af1925050503d8060008114610219576040519150601f19603f3d011682016040523d82523d6000602084013e61021e565b606091505b505090508061024857604051630e21dcbb60e11b81523360048201524760248201526044016101b0565b505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561028c5761028c61024d565b604052919050565b600067ffffffffffffffff8211156102ae576102ae61024d565b5060051b60200190565b600082601f8301126102c957600080fd5b813560206102de6102d983610294565b610263565b82815260059290921b840181019181810190868411156102fd57600080fd5b8286015b848110156103185780358352918301918301610301565b509695505050505050565b6000806040838503121561033657600080fd5b823567ffffffffffffffff8082111561034e57600080fd5b818501915085601f83011261036257600080fd5b813560206103726102d983610294565b82815260059290921b8401810191818101908984111561039157600080fd5b948201945b838610156103c55785356001600160a01b03811681146103b65760008081fd5b82529482019490820190610396565b965050860135925050808211156103db57600080fd5b506103e8858286016102b8565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561042a57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220463aa93b36bbf049bb9add61fc6e9f93ee69240841579c4af23fc9a58a9a1a0d64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c8063ffc3a76914610023575b600080fd5b610036610031366004610323565b610038565b005b805182511461005a5760405163a9cb9e0d60e01b815260040160405180910390fd5b60005b82518110156101cd5760006001600160a01b0316838281518110610083576100836103f2565b60200260200101516001600160a01b0316141561009f576101bb565b8181815181106100b1576100b16103f2565b6020026020010151600014156100c6576101bb565b60008382815181106100da576100da6103f2565b60200260200101516001600160a01b03168383815181106100fd576100fd6103f2565b602002602001015160405160006040518083038185875af1925050503d8060008114610145576040519150601f19603f3d011682016040523d82523d6000602084013e61014a565b606091505b50509050806101b957838281518110610165576101656103f2565b602002602001015183838151811061017f5761017f6103f2565b6020908102919091010151604051630e21dcbb60e11b81526001600160a01b03909216600483015260248201526044015b60405180910390fd5b505b806101c581610408565b91505061005d565b50476101d7575050565b604051600090339047908381818185875af1925050503d8060008114610219576040519150601f19603f3d011682016040523d82523d6000602084013e61021e565b606091505b505090508061024857604051630e21dcbb60e11b81523360048201524760248201526044016101b0565b505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561028c5761028c61024d565b604052919050565b600067ffffffffffffffff8211156102ae576102ae61024d565b5060051b60200190565b600082601f8301126102c957600080fd5b813560206102de6102d983610294565b610263565b82815260059290921b840181019181810190868411156102fd57600080fd5b8286015b848110156103185780358352918301918301610301565b509695505050505050565b6000806040838503121561033657600080fd5b823567ffffffffffffffff8082111561034e57600080fd5b818501915085601f83011261036257600080fd5b813560206103726102d983610294565b82815260059290921b8401810191818101908984111561039157600080fd5b948201945b838610156103c55785356001600160a01b03811681146103b65760008081fd5b82529482019490820190610396565b965050860135925050808211156103db57600080fd5b506103e8858286016102b8565b9150509250929050565b634e487b7160e01b600052603260045260246000fd5b600060001982141561042a57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220463aa93b36bbf049bb9add61fc6e9f93ee69240841579c4af23fc9a58a9a1a0d64736f6c634300080c0033", + "linkReferences": {}, + "deployedLinkReferences": {} +} From 7d79301e75a55ad6e999e64dea1206283432d9b9 Mon Sep 17 00:00:00 2001 From: ironbeer <7997273+ironbeer@users.noreply.github.com> Date: Fri, 10 Mar 2023 19:27:52 +0900 Subject: [PATCH 2/2] Added OASMultiTransfer test --- test/util/OASMultiTransfer.spec.ts | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/util/OASMultiTransfer.spec.ts diff --git a/test/util/OASMultiTransfer.spec.ts b/test/util/OASMultiTransfer.spec.ts new file mode 100644 index 0000000..cda8dcf --- /dev/null +++ b/test/util/OASMultiTransfer.spec.ts @@ -0,0 +1,55 @@ +import { BigNumber } from 'ethers' +import { ethers } from 'hardhat' +import { Contract } from 'ethers' +import { SignerWithAddress as Account } from '@nomiclabs/hardhat-ethers/signers' +import { expect } from 'chai' + +const parseUnits = ethers.utils.parseUnits + +const expectBalance = async (address: string, ether: BigNumber) => { + const actual = await ethers.provider.getBalance(address) + expect(actual).to.equal(ether) +} + +describe('OASMultiTransfer', () => { + let signer: Account + let contract: Contract + + before(async () => { + signer = (await ethers.getSigners())[0] + }) + + beforeEach(async () => { + const factory = await ethers.getContractFactory('OASMultiTransfer') + contract = (await factory.deploy()).connect(signer) + }) + + const tos = [ + '0xad2148f0E70f450974713AFcFD6991f03e14084A', + '0x0000000000000000000000000000000000000000', + '0xAFFe1007893bFCa4fB86f204a6C812e83C703452', + ] + const amounts = [parseUnits('1'), parseUnits('2'), parseUnits('3')] + + it('normally', async () => { + // check initial balance + await expectBalance(signer.address, parseUnits('10000')) + + // transfer + await contract.transfer(tos, amounts, { value: parseUnits('100') }) + + // check recipient balances + await expectBalance(tos[0], amounts[0]) + await expectBalance(tos[1], parseUnits('0')) + await expectBalance(tos[2], amounts[2]) + + // check refund + await expectBalance(contract.address, parseUnits('0')) + await expectBalance(signer.address, parseUnits('9996')) + }) + + it('value is shortage', async () => { + const tx = contract.transfer(tos, amounts, { value: parseUnits('1') }) + await expect(tx).to.be.revertedWith(`TransferFailed("${tos[2]}", ${amounts[2]})`) + }) +})