-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ron Turetzky
committed
Sep 23, 2024
1 parent
05aa9cd
commit 47bdbff
Showing
3 changed files
with
156 additions
and
3 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// VotingMultipliers.sol | ||
pragma solidity ^0.8.22; | ||
|
||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; | ||
import "./IMultiplier.sol"; | ||
import "../interfaces/IBread.sol"; | ||
|
||
contract VotingMultipliers is Initializable, OwnableUpgradeable { | ||
IBread public BREAD; | ||
IMultiplier[] public whitelistedMultipliers; | ||
IMultiplier[] public queuedMultipliersForAddition; | ||
IMultiplier[] public queuedMultipliersForRemoval; | ||
|
||
event MultiplierAdded(IMultiplier indexed multiplier); | ||
event MultiplierRemoved(IMultiplier indexed multiplier); | ||
|
||
function initialize(IBread _bread) public initializer { | ||
__Ownable_init(); | ||
BREAD = _bread; | ||
} | ||
|
||
function getTotalMultipliers(address user) external view returns (uint256) { | ||
uint256 totalMultiplier = 1e18; // Start with 100% (no multiplier) | ||
for (uint256 i = 0; i < whitelistedMultipliers.length; i++) { | ||
IMultiplier multiplier = whitelistedMultipliers[i]; | ||
if (block.number <= multiplier.validUntil(user)) { | ||
totalMultiplier += multiplier.getMultiplyingFactor(user); | ||
} | ||
} | ||
return totalMultiplier; | ||
} | ||
|
||
function queueMultiplierAddition(IMultiplier _multiplier) external onlyOwner { | ||
queuedMultipliersForAddition.push(_multiplier); | ||
} | ||
|
||
function queueMultiplierRemoval(IMultiplier _multiplier) external onlyOwner { | ||
queuedMultipliersForRemoval.push(_multiplier); | ||
} | ||
|
||
function updateMultipliers() external onlyOwner { | ||
// Add queued multipliers | ||
for (uint256 i = 0; i < queuedMultipliersForAddition.length; i++) { | ||
whitelistedMultipliers.push(queuedMultipliersForAddition[i]); | ||
emit MultiplierAdded(queuedMultipliersForAddition[i]); | ||
} | ||
delete queuedMultipliersForAddition; | ||
|
||
// Remove queued multipliers | ||
for (uint256 i = 0; i < queuedMultipliersForRemoval.length; i++) { | ||
for (uint256 j = 0; j < whitelistedMultipliers.length; j++) { | ||
if (whitelistedMultipliers[j] == queuedMultipliersForRemoval[i]) { | ||
whitelistedMultipliers[j] = whitelistedMultipliers[whitelistedMultipliers.length - 1]; | ||
whitelistedMultipliers.pop(); | ||
emit MultiplierRemoved(queuedMultipliersForRemoval[i]); | ||
break; | ||
} | ||
} | ||
} | ||
delete queuedMultipliersForRemoval; | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// IMultiplier.sol | ||
pragma solidity ^0.8.22; | ||
|
||
interface IMultiplier { | ||
function getMultiplyingFactor(address user) external view returns (uint256); | ||
function validUntil(address user) external view returns (uint256); | ||
} | ||
|
||
// INFTMultiplier.sol | ||
pragma solidity ^0.8.22; | ||
|
||
import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; | ||
import "./IMultiplier.sol"; | ||
|
||
interface INFTMultiplier is IMultiplier { | ||
function NFTAddress() external view returns (IERC721); | ||
function hasNFT(address user) external view returns (bool); | ||
} | ||
|
||
// PermanentNFTMultiplier.sol | ||
pragma solidity ^0.8.22; | ||
|
||
import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; | ||
import "./INFTMultiplier.sol"; | ||
|
||
contract PermanentNFTMultiplier is INFTMultiplier { | ||
IERC721 public immutable NFTAddress; | ||
uint256 public immutable multiplyingFactor; | ||
uint256 public constant validity = type(uint256).max; | ||
|
||
constructor(IERC721 _nftAddress, uint256 _multiplyingFactor) { | ||
NFTAddress = _nftAddress; | ||
multiplyingFactor = _multiplyingFactor; | ||
} | ||
|
||
function getMultiplyingFactor(address user) external view override returns (uint256) { | ||
return hasNFT(user) ? multiplyingFactor : 0; | ||
} | ||
|
||
function validUntil(address) external pure override returns (uint256) { | ||
return validity; | ||
} | ||
|
||
function hasNFT(address user) public view override returns (bool) { | ||
return NFTAddress.balanceOf(user) > 0; | ||
} | ||
} | ||
|
||
// DynamicNFTMultiplier.sol | ||
pragma solidity ^0.8.22; | ||
|
||
import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; | ||
import "./INFTMultiplier.sol"; | ||
|
||
contract DynamicNFTMultiplier is INFTMultiplier { | ||
IERC721 public immutable NFTAddress; | ||
mapping(address => uint256) public userToFactor; | ||
mapping(address => uint256) public userToValidity; | ||
|
||
constructor(IERC721 _nftAddress) { | ||
NFTAddress = _nftAddress; | ||
} | ||
|
||
function getMultiplyingFactor(address user) external view override returns (uint256) { | ||
return hasNFT(user) ? userToFactor[user] : 0; | ||
} | ||
|
||
function validUntil(address user) external view override returns (uint256) { | ||
return userToValidity[user]; | ||
} | ||
|
||
function hasNFT(address user) public view override returns (bool) { | ||
return NFTAddress.balanceOf(user) > 0; | ||
} | ||
|
||
function setUserFactor(address user, uint256 factor, uint256 validity) external { | ||
// Add appropriate access control | ||
require(hasNFT(user), "User does not have the required NFT"); | ||
userToFactor[user] = factor; | ||
userToValidity[user] = validity; | ||
} | ||
} |