Hi i am creating a wallet with which i can transfer ETH on approval from 3 authorised address. My second test condition fails. I am fairly new to solidity please help.
wallet.js
const Wallet = artifacts.require('Wallet');
contract('Wallet',(accounts) => {
let wallet;
beforeEach(async () =>{
wallet = await Wallet.new([accounts[0],accounts[1],accounts[2]],2);
await web3.eth.sendTransaction({from:accounts[0], to:wallet.address, value: 1000});
});
it('should heve correct approvers and quorum',async()=> {
const approvers = await wallet.getApprovers();
const quorum = await wallet.quorum();
assert(approvers.length === 3);
assert(approvers[0]===accounts[0]);
assert(approvers[1]===accounts[1]);
assert(approvers[2]===accounts[2]);
assert(quorum.toNumber() === 2);
});
it('should create transfers',async () => {
await wallet.createTransfer(100, accounts[5], {from: accounts[0]});
const transfers = await wallet.getTransfers();
assert(transfers.length === 1);
assert(transfers[0].id === '0');
assert(transfers[0].amount ==='100');
assert(transfers[0].to === accounts[5]);
assert(transfers[0].approval === '0');
assert(transfers[0].sent === false);
});
});
wallet.sol
//SPDX-License-Identifier:MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
contract Wallet{
//address array stores address of the approvers.
//quorum is the number of approvers.
address[] public approvers;
uint public quorum;
struct Transfer{
uint id;
uint amount;
address payable to;
uint approval;
bool sent;
}
Transfer[] public transfers;
// mapping(uint => Transfer) public transfers;
mapping(address => mapping(uint => bool)) public approvals;
constructor(address[] memory _approvers, uint _quorum)public{
approvers = _approvers;
quorum = _quorum;
}
function getApprovers() external view returns(address[] memory){
return approvers;
}
function getTransfers() external view returns(Transfer[] memory){
return transfers;
}
function createTransfer(uint amount, address payable to) external onlyApprovers(){
transfers.push(Transfer(
transfers.length,
amount,
to,
0,
false
));
}
function approveTransfer(uint id)external onlyApprovers(){
require(transfers[id].sent == false,'transfer has already been sent');
require(approvals[msg.sender][id]== false,'cannot approve transfer twice');
approvals[msg.sender][id]=true;
transfers[id].approval++;
if(transfers[id].approval >= quorum){
transfers[id].sent = true;
address payable to = transfers[id].to;
uint amount = transfers[id].amount;
to.transfer(amount);
}
}
receive() external payable{}
modifier onlyApprovers(){
bool allowed =false;
for(uint i=0;i<= approvers.length;i++){
if(approvers[i] == msg.sender){
allowed =true;
}
}
require(allowed=true,'only approvers can approve');
_;
}
}
I am getting this error when testing.
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/Wallet.sol
> Artifacts written to /var/folders/kx/64r1zrfn28g8v6_sy50p98480000gn/T/test--50180-yxWHgIg50Wuu
> Compiled successfully using:
- solc: 0.6.0+commit.26b70077.Emscripten.clang
Contract: Wallet
✔ should heve correct approvers and quorum (64ms)
1) should create transfers
> No events were emitted
1 passing (6s)
1 failing
1) Contract: Wallet
should create transfers:
Transaction: 0xd41ddeb4f3801cd59e065679a8a26180d92aa31778704e16ccfde77e01b9d830 exited with an error (status 0) after consuming all gas.
Please check that the transaction:
- satisfies all conditions set by Solidity `assert` statements.
- has enough gas to execute the full transaction.
- does not trigger an invalid opcode by other means (ex: accessing an array out of bounds).
StatusError: Transaction: 0xd41ddeb4f3801cd59e065679a8a26180d92aa31778704e16ccfde77e01b9d830 exited with an error (status 0) after consuming all gas.
at Context.<anonymous> (test/Wallet.js:21:17)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
I am new to solidity please help.I tried including gas and gasPrice directly to my transaction still the issue was not solved.