Skip to content

Commit

Permalink
adds option to locking crowdsales to trust other locked token initiators
Browse files Browse the repository at this point in the history
Signed-off-by: Stefan Adolf <[email protected]>
  • Loading branch information
elmariachi111 committed Dec 19, 2024
1 parent d9a4102 commit a806488
Show file tree
Hide file tree
Showing 9 changed files with 995 additions and 3 deletions.
1 change: 1 addition & 0 deletions script/prod/RolloutV25Sale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ contract RolloutV25LockingSale is Script {
function run() public {
//mainnet 0xCfA0F84660fB33bFd07C369E5491Ab02C449f71B;
address moleculeDevMultisig = 0x9d5a6ae551f1117946FF6e0e86ef9A1B20C90Cb0;
address stakedLockingCrowdsale = 0xd1cE2EA7d3b0C9cAB025A4aD762FC00315141ad7;
TimelockedToken timelockedTokenImplementation = TimelockedToken(0xF8F79c1E02387b0Fc9DE0945cD9A2c06F127D851);

vm.startBroadcast();
Expand Down
23 changes: 20 additions & 3 deletions src/crowdsale/LockingCrowdSale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,27 @@ import { CrowdSale, Sale } from "./CrowdSale.sol";
error UnsupportedInitializer();
error InvalidDuration();

interface ITrustedLockingContracts {
function lockingContracts(address) external view returns (TimelockedToken);
}

/**
* @title LockingCrowdSale
* @author molecule.to
* @notice a fixed price sales base contract that locks the sold tokens for a configurable duration
*/
contract LockingCrowdSale is CrowdSale {
contract LockingCrowdSale is CrowdSale, ITrustedLockingContracts {
using SafeERC20 for IERC20Metadata;

mapping(uint256 => uint256) public salesLockingDuration;

/// @notice map from token address to reusable TimelockedToken contracts
mapping(address => TimelockedToken) public lockingContracts;

///@notice this can be another contract registry that takes care of locking contracts
/// to reuse implementations
ITrustedLockingContracts public lockingContractTrustee;

address immutable public TIMELOCKED_TOKEN_IMPLEMENTATION;

event Started(uint256 indexed saleId, address indexed issuer, Sale sale, TimelockedToken lockingToken, uint256 lockingDuration, uint16 feeBp);
Expand All @@ -39,6 +47,10 @@ contract LockingCrowdSale is CrowdSale {
revert UnsupportedInitializer();
}

function trustLockingContractSource(ITrustedLockingContracts _lockingContractTrustee) public onlyOwner {
lockingContractTrustee = _lockingContractTrustee;
}

/**
* @notice allows anyone to create a timelocked token that's controlled by this sale contract
* helpful if you want to reuse the timelocked token for your own custom schedules
Expand All @@ -50,8 +62,13 @@ contract LockingCrowdSale is CrowdSale {
lockedTokenContract = lockingContracts[address(underlyingToken)];

if (address(lockedTokenContract) == address(0)) {
lockedTokenContract = _makeNewLockedTokenContract(underlyingToken);
lockingContracts[address(underlyingToken)] = lockedTokenContract;
if (address(lockingContractTrustee) != address(0)) {
lockedTokenContract = lockingContractTrustee.lockingContracts(address(underlyingToken));
}
if (address(lockedTokenContract) == address(0)) {
lockedTokenContract = _makeNewLockedTokenContract(underlyingToken);
lockingContracts[address(underlyingToken)] = lockedTokenContract;
}
}
}

Expand Down
19 changes: 19 additions & 0 deletions subgraph/abis/IPNFT.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,25 @@
],
"stateMutability": "view"
},
{
"type": "function",
"name": "isPoi",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "pure"
},
{
"type": "function",
"name": "mintReservation",
Expand Down
Loading

0 comments on commit a806488

Please sign in to comment.