Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge master #235

Merged
merged 5 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions packages/app/src/hooks/useIsStewardVerified.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
import { G$ContractAddresses, CONTRACT_TO_ABI } from '@gooddollar/web3sdk-v2';
import { G$ContractAddresses } from '@gooddollar/web3sdk-v2';
import { isAddress, zeroAddress } from 'viem';
import { useContractRead, useNetwork } from 'wagmi';

export const useIsStewardVerified = (address: string): boolean => {
const chain = useNetwork();
const idAddress = G$ContractAddresses('Identity', 'production-celo') as `0x{string}`;
const abi = CONTRACT_TO_ABI.Identity.abi;
const result = useContractRead({
chainId: chain.chain?.id,
abi,
abi: [
{
inputs: [
{
internalType: 'address',
name: 'account',
type: 'address',
},
],
name: 'getWhitelistedRoot',
outputs: [
{
internalType: 'address',
name: 'whitelisted',
type: 'address',
},
],
stateMutability: 'view',
type: 'function',
},
],
address: idAddress,
args: [address],
functionName: 'isWhitelisted',
functionName: 'getWhitelistedRoot',
});

return result.data as any as boolean;
return result.data !== zeroAddress && isAddress(result.data as any);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import { AccessControlUpgradeable } from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

import "hardhat/console.sol";
// import "hardhat/console.sol";

contract DirectPaymentsFactory is AccessControlUpgradeable, UUPSUpgradeable {
error NOT_PROJECT_OWNER();
Expand Down Expand Up @@ -98,31 +98,37 @@ contract DirectPaymentsFactory is AccessControlUpgradeable, UUPSUpgradeable {
string memory _projectId,
string memory _ipfs,
DirectPaymentsPool.PoolSettings memory _settings,
DirectPaymentsPool.SafetyLimits memory _limits
DirectPaymentsPool.SafetyLimits memory _limits,
uint32 _managerFeeBps
) external onlyProjectOwnerOrNon(_projectId) returns (DirectPaymentsPool pool) {
return _createPool(_projectId, _ipfs, _settings, _limits, true);
return _createPool(_projectId, _ipfs, _settings, _limits, _managerFeeBps, true);
}

function createPool(
string memory _projectId,
string memory _ipfs,
DirectPaymentsPool.PoolSettings memory _settings,
DirectPaymentsPool.SafetyLimits memory _limits
DirectPaymentsPool.SafetyLimits memory _limits,
uint32 _managerFeeBps
) external onlyProjectOwnerOrNon(_projectId) returns (DirectPaymentsPool pool) {
return _createPool(_projectId, _ipfs, _settings, _limits, false);
return _createPool(_projectId, _ipfs, _settings, _limits, _managerFeeBps, false);
}

function _createPool(
string memory _projectId,
string memory _ipfs,
DirectPaymentsPool.PoolSettings memory _settings,
DirectPaymentsPool.SafetyLimits memory _limits,
uint32 _managerFeeBps,
bool useBeacon
) internal returns (DirectPaymentsPool pool) {
//TODO: add check if msg.sender is whitelisted

_settings.nftType = nextNftType;
bytes memory initCall = abi.encodeCall(DirectPaymentsPool.initialize, (nft, _settings, _limits, this));
bytes memory initCall = abi.encodeCall(
DirectPaymentsPool.initialize,
(nft, _settings, _limits, _managerFeeBps, this)
);

if (useBeacon) {
pool = DirectPaymentsPool(address(new BeaconProxy(address(impl), initCall)));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import "./DirectPaymentsPool.sol";

library DirectPayemntsLibrary {
function _updateMemberLimits(
DirectPaymentsPool.LimitsData storage memberStats,
uint128 reward,
uint64 curMonth
) internal {
if (memberStats.lastReward + 60 * 60 * 24 < block.timestamp) //more than a day passed since last reward
{
memberStats.daily = reward;
} else {
memberStats.daily += reward;
}

if (memberStats.lastMonth < curMonth) //month switched
{
memberStats.monthly = reward;
} else {
memberStats.monthly += reward;
}

memberStats.total += reward;
memberStats.lastReward = uint64(block.timestamp);
memberStats.lastMonth = curMonth;
}

function _updateGlobalLimits(
DirectPaymentsPool.LimitsData storage globalLimits,
uint128 reward,
uint64 curMonth
) internal {
if (globalLimits.lastReward + 60 * 60 * 24 < block.timestamp) //more than a day passed since last reward
{
globalLimits.daily = reward;
} else {
globalLimits.daily += reward;
}

if (globalLimits.lastMonth < curMonth) //month switched
{
globalLimits.monthly = reward;
} else {
globalLimits.monthly += reward;
}

globalLimits.total += reward;
globalLimits.lastReward = uint64(block.timestamp);
globalLimits.lastMonth = curMonth;
}
}
51 changes: 13 additions & 38 deletions packages/contracts/contracts/DirectPayments/DirectPaymentsPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IERC721ReceiverUpgradeable } from "@openzeppelin/contracts-upgradeable/

import { ProvableNFT } from "./ProvableNFT.sol";
import { DirectPaymentsFactory } from "./DirectPaymentsFactory.sol";
import { DirectPayemntsLibrary } from "./DirectPaymentsLibrary.sol";
import "../GoodCollective/GoodCollectiveSuperApp.sol";

interface IMembersValidator {
Expand Down Expand Up @@ -111,6 +112,8 @@ contract DirectPaymentsPool is
LimitsData public globalLimits;
DirectPaymentsFactory public registry;

uint32 public managerFeeBps;

/// @custom:oz-upgrades-unsafe-allow constructor
constructor(ISuperfluid _host, IV3SwapRouter _swapRouter) GoodCollectiveSuperApp(_host, _swapRouter) {}

Expand All @@ -124,6 +127,10 @@ contract DirectPaymentsPool is
return IRegistry(address(registry));
}

function getManagerFee() public view override returns (address feeRecipient, uint32 feeBps) {
return (settings.manager, managerFeeBps);
}

/**
* @dev Initializes the contract with the given settings and limits.
* @param _nft The ProvableNFT contract address.
Expand All @@ -134,12 +141,14 @@ contract DirectPaymentsPool is
ProvableNFT _nft,
PoolSettings memory _settings,
SafetyLimits memory _limits,
uint32 _managerFeeBps,
DirectPaymentsFactory _registry
) external initializer {
registry = _registry;
settings = _settings;
limits = _limits;
nft = _nft;
managerFeeBps = _managerFeeBps;
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender); // when using factory this gives factory role which then set role to the real msg.sender
_setupRole(MANAGER_ROLE, _settings.manager);
_setupRole(MINTER_ROLE, _settings.manager);
Expand Down Expand Up @@ -259,24 +268,7 @@ contract DirectPaymentsPool is
return false;
}

uint64 curMonth = _month();
if (memberLimits[member].lastReward + 60 * 60 * 24 < block.timestamp) //more than a day passed since last reward
{
memberLimits[member].daily = reward;
} else {
memberLimits[member].daily += reward;
}

if (memberLimits[member].lastMonth < curMonth) //month switched
{
memberLimits[member].monthly = reward;
} else {
memberLimits[member].monthly += reward;
}

memberLimits[member].total += reward;
memberLimits[member].lastReward = uint64(block.timestamp);
memberLimits[member].lastMonth = curMonth;
DirectPayemntsLibrary._updateMemberLimits(memberLimits[member], reward, _month());

if (
memberLimits[member].daily > limits.maxMemberPerDay ||
Expand All @@ -291,25 +283,7 @@ contract DirectPaymentsPool is
* @param reward The amount of rewards to enforce and update limits for.
*/
function _enforceAndUpdateGlobalLimits(uint128 reward) internal {
uint64 curMonth = _month();

if (globalLimits.lastReward + 60 * 60 * 24 < block.timestamp) //more than a day passed since last reward
{
globalLimits.daily = reward;
} else {
globalLimits.daily += reward;
}

if (globalLimits.lastMonth < curMonth) //month switched
{
globalLimits.monthly = reward;
} else {
globalLimits.monthly += reward;
}

globalLimits.total += reward;
globalLimits.lastReward = uint64(block.timestamp);
globalLimits.lastMonth = curMonth;
DirectPayemntsLibrary._updateGlobalLimits(globalLimits, reward, _month());

if (globalLimits.monthly > limits.maxTotalPerMonth) revert OVER_GLOBAL_LIMITS();
}
Expand Down Expand Up @@ -409,7 +383,8 @@ contract DirectPaymentsPool is
* @dev Sets the settings for the pool.
* @param _settings The new pool settings.
*/
function setPoolSettings(PoolSettings memory _settings) public onlyRole(MANAGER_ROLE) {
function setPoolSettings(PoolSettings memory _settings, uint32 _managerFeeBps) public onlyRole(MANAGER_ROLE) {
managerFeeBps = _managerFeeBps;
if (_settings.nftType != settings.nftType) revert NFTTYPE_CHANGED();
if (_settings.manager == address(0)) revert EMPTY_MANAGER();

Expand Down
Loading
Loading