Hello, im new here and i have been playing around with PaymentSplitter.
However, after following the steps, adding the wallets etc... i can contract call on BSCScan and pull the funds available on that contract without being a beneficiary / my wallet being on the contract.
Is this a bug or is there something wrong with the code?
What im trying todo, the funds on there to be only accessible by the Wallets i typed on Deploy.
Code one, and vulnerable... Meaning, Wallets not added on deploy, can still access funds on BSCScan
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (finance/PaymentSplitter.sol)
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/finance/PaymentSplitter.sol";
code 2 and vulnerable, Meaning, Wallets not added on deploy, can still access funds on BSCScan
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "https://github.com/chnejohnson/splitter/blob/master/contracts/contracts/PaymentSplitter.sol";
contract Splitter is PaymentSplitter {
address public immutable owner;
enum State {
Opening,
Finalized
}
State public state = State.Opening;
event Finalized();
constructor(
address _owner,
address[] memory _payees,
uint256[] memory _shares
) PaymentSplitter(_payees, _shares) {
owner = _owner;
}
modifier onlyOwner() {
require(msg.sender == owner, "Splitter: caller is not the owner");
_;
}
modifier requireState(State _state) {
require(state == _state, "Splitter: not in required state");
_;
}
function totalPayees() public view returns (uint256) {
return _payees.length;
}
function isPayee(address account) public view returns (bool) {
return _shares[account] > 0;
}
function addPayee(address account, uint256 shares_) public onlyOwner requireState(State.Opening) {
_addPayee(account, shares_);
}
function addPayees(address[] memory payees, uint256[] memory shares_) public onlyOwner requireState(State.Opening) {
for (uint256 i = 0; i < payees.length; i++) {
_addPayee(payees[i], shares_[i]);
}
}
function finalize() public onlyOwner requireState(State.Opening) {
state = State.Finalized;
emit Finalized();
}
// override: only Finalized state can release
function release(address payable account) public override requireState(State.Finalized) {
require(_shares[account] > 0, "Splitter: account has no shares");
uint256 totalReceived = address(this).balance + _totalReleased;
uint256 payment = (totalReceived * _shares[account]) / _totalShares - _released[account];
require(payment != 0, "Splitter: account is not due payment");
_released[account] = _released[account] + payment;
_totalReleased = _totalReleased + payment;
Address.sendValue(account, payment);
emit PaymentReleased(account, payment);
}
}
Example, on the TestNet
Wallet on the Contract
0xE5D3c49bF2b8Ef077e37f22BD479580A686a8E8a
Anyone can remove funds, just by adding the wallet.
What im trying todo, is only Wallets on contract can remove funds.
Any help, i would really appreciate it.
Thanks!