1
0
Files
Kanel42_token/code/knlWallet.sol
2025-08-10 20:03:25 +02:00

112 lines
3.1 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import "./lib/forge-std/src/interfaces/IERC20.sol";
contract knlWallet {
struct Transaction {
address destination;
uint256 value;
bool executed;
address tokenAddress;
}
address[] public owners;
uint256 public required;
uint256 public transactionCount;
mapping(uint256 => Transaction) public transactions;
mapping(uint256 => mapping(address => bool)) public confirmations;
constructor(address[] memory _owners, uint256 _confirmations) {
require(_owners.length > 0, "need to have owners");
require(_confirmations > 0, "need to have a number of confirmation");
require(
_confirmations <= _owners.length,
"need to have more or equals owners than confirmation"
);
owners = _owners;
required = _confirmations;
}
modifier isOwner() {
for (uint256 i = 0; i < owners.length; i++) {
if (owners[i] == msg.sender) {
_;
return;
}
}
revert("need to be owner");
}
receive() external payable { }
function isConfirmed(uint256 transactionId) public view returns (bool) {
return getConfirmationsCount(transactionId) >= required;
}
function getConfirmationsCount(uint256 transactionId)
public
view
returns (uint256)
{
uint256 count;
for (uint256 i = 0; i < owners.length; i++) {
if (confirmations[transactionId][owners[i]]) {
count++;
}
}
return count;
}
function addTransaction(
address destination,
uint256 value,
address tokenAddress
) public isOwner returns (uint256) {
transactions[transactionCount] =
Transaction(destination, value, false, tokenAddress);
transactionCount += 1;
return transactionCount - 1;
}
function confirmTransaction(uint256 transactionId) public isOwner {
confirmations[transactionId][msg.sender] = true;
if (isConfirmed(transactionId)) {
executeTransaction(transactionId);
}
}
function submitTransaction(
address payable dest,
uint256 value,
address tokenAddress
) external isOwner {
uint256 id = addTransaction(dest, value, tokenAddress);
confirmTransaction(id);
}
function executeTransaction(uint256 transactionId) public isOwner {
require(isConfirmed(transactionId), "transaction has not been confirmed");
Transaction storage _tx = transactions[transactionId];
if (_tx.tokenAddress == address(0)) {
// Handle Ether transfer
(bool success,) = _tx.destination.call{ value: _tx.value }("");
require(success);
} else {
// Handle ERC-20 token transfer
IERC20 token = IERC20(_tx.tokenAddress);
require(
token.transfer(_tx.destination, _tx.value),
"Failed to transfer ERC20 tokens"
);
}
_tx.executed = true;
}
}