1
0
forked from mico/idle_moloch
idle_moloch/lib/Baal/contracts/higherOrderFactories/BaalAdvTokenSummoner.sol
2024-11-01 11:55:27 +01:00

189 lines
6.5 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;
import "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol";
import "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "../Baal.sol";
import "../interfaces/IBaalSummoner.sol";
contract BaalAdvTokenSummoner is
Initializable,
OwnableUpgradeable,
UUPSUpgradeable
{
IBaalSummoner public _baalSummoner;
event setSummoner(address summoner);
event DeployBaalTokens(address lootToken, address sharesToken);
constructor() {
_disableInitializers();
}
function initialize() public initializer {
__Ownable_init();
__UUPSUpgradeable_init();
}
/**
* @dev Sets the address of the BaalSummoner contract
* @param baalSummoner The address of the BaalSummoner contract
*/
function setSummonerAddr(address baalSummoner) public onlyOwner {
require(baalSummoner != address(0), "zero address");
_baalSummoner = IBaalSummoner(baalSummoner);
emit setSummoner(baalSummoner);
}
/**
* @dev Summon a new Baal contract with a new set of tokens
* @param _safeAddr The address of the Gnosis Safe to be used as the treausry, 0x0 if new Safe
* @param _forwarderAddr The address of the forwarder to be used, 0x0 if not set
* @param _saltNonce The salt nonce to be used for the Safe contract
* @param initializationMintParams The parameters for minting the tokens
* @param initializationTokenParams The parameters for deploying the tokens
* @param postInitializationActions The actions to be performed after the initialization
*/
function summonBaalFromReferrer(
address _safeAddr,
address _forwarderAddr,
uint256 _saltNonce,
bytes calldata initializationMintParams,
bytes calldata initializationTokenParams,
bytes[] calldata postInitializationActions
) external {
// summon tokens
(address _lootToken, address _sharesToken) = deployTokens(
initializationTokenParams
);
// mint shares loot tokens
mintTokens(initializationMintParams, _lootToken, _sharesToken);
// summon baal with new tokens
address _baal = _baalSummoner.summonBaalFromReferrer(
abi.encode(
IBaalToken(_sharesToken).name(),
IBaalToken(_sharesToken).symbol(),
_safeAddr,
_forwarderAddr,
_lootToken,
_sharesToken
),
postInitializationActions,
_saltNonce,
bytes32(bytes("DHAdvTokenSummoner")) // referrer
);
// change token ownership to baal
IBaalToken(_lootToken).transferOwnership(address(_baal));
IBaalToken(_sharesToken).transferOwnership(address(_baal));
}
/**
* @dev mintTokens
* @param initializationTokens The parameters for minting the tokens
* @param _lootToken The loot token address
* @param _sharesToken The shares token address
*/
function mintTokens(
bytes calldata initializationTokens,
address _lootToken,
address _sharesToken
) internal {
(
address[] memory summoners, // The address to mint initial tokens to
uint256[] memory summonerShares, // The amount of shares to mint
uint256[] memory summonerLoot // The amount of loot to mint
) = abi.decode(initializationTokens, (address[], uint256[], uint256[]));
require(
summoners.length == summonerShares.length &&
summoners.length == summonerLoot.length,
"!array parity"
); /*check array lengths match*/
for (uint256 i = 0; i < summoners.length; i++) {
if (summonerLoot[i] > 0) {
IBaalToken(_lootToken).mint(
summoners[i],
summonerLoot[i]
); /*grant `to` `amount` `loot`*/
}
if (summonerShares[i] > 0) {
IBaalToken(_sharesToken).mint(
summoners[i],
summonerShares[i]
); /*grant `to` `amount` `shares`*/
}
}
}
/**
* @dev deployTokens
* @param initializationParams The parameters for deploying the tokens
*/
function deployTokens(
bytes calldata initializationParams
) internal returns (address lootToken, address sharesToken) {
(
string
memory _name /*_name Name for erc20 `shares` accounting, empty if token */,
string
memory _symbol /*_symbol Symbol for erc20 `shares` accounting, empty if token*/,
string
memory _lootName /* name for erc20 `loot` accounting, empty if token */,
string
memory _lootSymbol /* symbol for erc20 `loot` accounting, empty if token*/,
bool _transferableShares /* if shares is transferable */,
bool _transferableLoot /* if loot is transferable */
) = abi.decode(
initializationParams,
(string, string, string, string, bool, bool)
);
address lootSingleton = _baalSummoner.lootSingleton();
address sharesSingleton = _baalSummoner.sharesSingleton();
lootToken = address(
new ERC1967Proxy(
lootSingleton,
abi.encodeWithSelector(
IBaalToken(lootSingleton).setUp.selector,
_lootName,
_lootSymbol
)
)
);
sharesToken = address(
new ERC1967Proxy(
sharesSingleton,
abi.encodeWithSelector(
IBaalToken(sharesSingleton).setUp.selector,
_name,
_symbol
)
)
);
if (!_transferableShares) {
IBaalToken(sharesToken).pause();
}
if (!_transferableLoot) {
IBaalToken(lootToken).pause();
}
emit DeployBaalTokens(lootToken, sharesToken);
}
function _authorizeUpgrade(
address newImplementation
) internal override onlyOwner {}
}