This is my first post on this stack exchange site and it comes after a couple of hours of banging my head against this error's wall.
In short, I am currently going through a solidity course and one of the projects I am working on is a "shared wallet" concept with different roles (in my example below admin, family, approved spender), an allowance/role and a concept of "remaining balance" for each address that has at least 1 role assigned (i.e member).
The problem I am facing and which I cannot understand is why do I get this error "Note: The called function should be payable if you send value and the value you send should be less than your current balance." when running the "SetAllowance" function? What I cannot understand is why is the notion of "payable" invoked in the error returned when running a function that does not include any "payable" like method (i.e transfer, call, send)?!
My code below:
//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";
contract SharedWallet is Ownable, AccessControl {
using SafeMath for uint256;
event BalanceReceived (address indexed _from, uint256 _amount);
event AmountSpent (address indexed _by, address indexed _to, uint256 _amount);
bytes32 public constant FAMILY_ROLE = keccak256("FAMILY");
bytes32 public constant ApprovedSpender_ROLE = keccak256("ApprovedSpender");
mapping(bytes32 => uint256) public allowance;
mapping(address => uint256) public remainingBalance;
address payable[] internal AllFamilyAcc;
address payable[] internal AllAppSpendersAcc;
constructor () public {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
allowance[FAMILY_ROLE] = 1 ether;
allowance[ApprovedSpender_ROLE] = 2 ether;
}
modifier onlyAdmin() {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender));
_;
}
modifier OnlyMembers() {
require(hasRole(ApprovedSpender_ROLE, msg.sender) || hasRole(FAMILY_ROLE, msg.sender) || hasRole(DEFAULT_ADMIN_ROLE, msg.sender));
_;
}
function SetAllowance(uint256 _FamilyAmount, uint256 _AppSpenderAmount)
public payable
{
for (uint i=0; i<=AllFamilyAcc.length; i++) {
remainingBalance[AllFamilyAcc[i]] += _FamilyAmount;
}
for (uint i=0; i<=AllAppSpendersAcc.length; i++) {
remainingBalance[AllAppSpendersAcc[i]] += _AppSpenderAmount;
}
}
function addFamilyMember(address payable _account)
public virtual
{
require(!hasRole(FAMILY_ROLE, _account),"Already a family member!");
grantRole(FAMILY_ROLE, _account);
remainingBalance[_account] = allowance[FAMILY_ROLE];
AllFamilyAcc.push(payable(_account));
}
function addApprovedSpender(address payable _account)
public virtual
{
require(!hasRole(ApprovedSpender_ROLE, _account),"Already an approved spender!");
grantRole(ApprovedSpender_ROLE, _account);
remainingBalance[_account]=allowance[ApprovedSpender_ROLE];
AllAppSpendersAcc.push(payable(_account));
}
}
Thanks in advance!