Created
September 6, 2023 19:58
-
-
Save Falilah/ce3c6010aac9f7fc962245b3b6aeaa8d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ethers } from 'hardhat' | |
async function main() { | |
const currentTimestampInSeconds = Math.round(Date.now() / 1000) | |
const unlockTime = currentTimestampInSeconds + 60 | |
const lockedAmount = ethers.parseEther('0.001') | |
const lock = await ethers.deployContract('Lock', [unlockTime], { | |
value: lockedAmount, | |
}) | |
await lock.waitForDeployment() | |
console.log( | |
`Lock with ${ethers.formatEther( | |
lockedAmount | |
)}ETH and unlock timestamp ${unlockTime} deployed to ${lock.target}` | |
) | |
let [bal, time] = await lock.returnValues() | |
console.log( | |
` current Locked AMount:${ethers.formatEther( | |
bal | |
)}, The unlock Time is ${new Date(Number(time) * 1000)}` | |
) | |
} | |
// We recommend this pattern to be able to use async/await everywhere | |
// and properly handle errors. | |
main().catch((error) => { | |
console.error(error) | |
process.exitCode = 1 | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.19; | |
// a multisig Wallet | |
// contract should accept ether | |
// array of signatories | |
// approving transaction | |
// mapping address to bool for valid Admins | |
//mapping uint => address => bool to track approval of each admin on each transaction | |
// transaction Detail | |
contract MultiSig { | |
struct Transaction { | |
address spender; | |
uint amount; | |
uint numberOfApproval; | |
bool isActive; | |
} | |
address[] Admins; | |
uint constant MINIMUM = 3; | |
uint transactionId; | |
mapping(address => bool) isAdmin; | |
mapping(uint => Transaction) transaction; | |
mapping(uint => mapping(address => bool)) hasApproved; | |
error InvalidAddress(uint position); | |
error InvalidAdminNumber(uint number); | |
error duplicate(address _addr); | |
event Create(address who, address spender, uint amount); | |
modifier onlyAdmin() { | |
require(isAdmin[msg.sender], "Not a Valid Admin"); | |
_; | |
} | |
constructor(address[] memory _admins) payable { | |
if (_admins.length < MINIMUM) { | |
revert InvalidAdminNumber(MINIMUM); | |
} | |
for (uint i = 0; i < _admins.length; i++) { | |
if (_admins[i] == address(0)) { | |
revert InvalidAddress(i + 1); | |
} | |
if (isAdmin[_admins[i]]) { | |
revert duplicate(_admins[i]); | |
} | |
isAdmin[_admins[i]] = true; | |
} | |
Admins = _admins; | |
} | |
function createTransaction( | |
uint amount, | |
address _spender | |
) external onlyAdmin { | |
transactionId++; | |
Transaction storage _transaction = transaction[transactionId]; | |
_transaction.amount = amount; | |
_transaction.spender = _spender; | |
_transaction.isActive = true; | |
emit Create(msg.sender, _spender, amount); | |
AprroveTransaction(transactionId); | |
} | |
function AprroveTransaction(uint id) public onlyAdmin { | |
//check if addmin has not approved yet; | |
require(!hasApproved[id][msg.sender], "Already Approved!!"); | |
hasApproved[id][msg.sender] = true; | |
Transaction storage _transaction = transaction[id]; | |
require(_transaction.isActive, "Not active"); | |
_transaction.numberOfApproval += 1; | |
uint count = _transaction.numberOfApproval; | |
uint MinApp = calculateMinimumApproval(); | |
if (count >= MinApp) { | |
sendtransaction(id); | |
} | |
} | |
function sendtransaction(uint id) internal { | |
Transaction storage _transaction = transaction[id]; | |
payable(_transaction.spender).transfer(_transaction.amount); | |
_transaction.isActive = false; | |
} | |
function calculateMinimumApproval() public view returns (uint MinApp) { | |
uint size = Admins.length; | |
MinApp = (size * 70) / 100; | |
} | |
function getTransaction( | |
uint id | |
) external view returns (Transaction memory) { | |
return transaction[id]; | |
} | |
receive() external payable {} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ethers } from 'hardhat' | |
async function main() { | |
const [Admin1, Admin2, Admin3, Admin4, Admin5, spender] = | |
await ethers.getSigners() | |
const Owners = [ | |
Admin1.address, | |
Admin2.address, | |
Admin3.address, | |
Admin4.address, | |
Admin5.address, | |
] | |
const multisig = await ethers.deployContract('MultiSig', [Owners], { | |
value: ethers.parseEther('10'), | |
}) | |
await multisig.waitForDeployment() | |
console.log(`Multisig deployed to ${multisig.target}`) | |
const amount = ethers.parseEther('5') | |
const receipt = await multisig.createTransaction(amount, spender.address) | |
const receipt2 = await multisig | |
.connect(Admin2) | |
.createTransaction(amount, spender.address) | |
const receipt3 = await multisig | |
.connect(Admin3) | |
.createTransaction(amount, spender.address) | |
const receipt4 = await multisig.createTransaction(amount, spender.address) | |
const receipt5 = await multisig.createTransaction(amount, spender.address) | |
//returns the event args | |
//@ts-ignore | |
console.log(await (await receipt.wait())?.logs[0]?.args) | |
await multisig.connect(Admin3).AprroveTransaction(1) | |
let balancebefore = await ethers.provider.getBalance(spender.address) | |
console.log(`balance before ${ethers.formatEther(balancebefore)}`) | |
await multisig.connect(Admin2).AprroveTransaction(1) | |
console.log( | |
`Spender Balance ${ethers.formatEther( | |
(await ethers.provider.getBalance(spender.address)) - balancebefore | |
)})` | |
) | |
let [add, _amount, approval, isActive] = await multisig.getTransaction(1) | |
console.log( | |
add, | |
ethers.formatEther(_amount), | |
parseInt(String(approval)), | |
isActive | |
) | |
} | |
// We recommend this pattern to be able to use async/await everywhere | |
// and properly handle errors. | |
main().catch((error) => { | |
console.error(error) | |
process.exitCode = 1 | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment