Skip to content

Commit

Permalink
fix: renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
Picodes committed Apr 17, 2024
1 parent 563c3e4 commit 487d2f8
Show file tree
Hide file tree
Showing 10 changed files with 1,256 additions and 47 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.17;

import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

import "../utils/UUPSHelper.sol";

Expand All @@ -13,29 +13,16 @@ interface IDistributionCreator {
function feeRecipient() external view returns (address);

Check failure on line 13 in contracts/tokenWrappers/BaseTokenWrapper.sol

View workflow job for this annotation

GitHub Actions / lint

Insert ⏎
}

interface IVesting {
function rdntToken() external view returns (address);
function vestTokens(address, uint256, bool) external returns (address);
}

/// @title Radiant Coupon
/// @dev This token can only be held by merkl distributor
/// @dev Transferring to the distributor will require transferring the underlying token to this contract
/// @dev Transferring from the distributor will trigger vesting action
/// @dev Transferring token to the distributor is permissionless so anyone could mint coupons - the only
/// impact would be to forfeit these tokens
contract RadiantCoupon is UUPSHelper, ERC20Upgradeable {
abstract contract BaseMerklTokenWrapper is UUPSHelper, ERC20Upgradeable {
using SafeERC20 for IERC20;

// ================================= CONSTANTS =================================

IVesting public constant VESTING = IVesting(0x76ba3eC5f5adBf1C58c91e86502232317EeA72dE);
IDistributionCreator public constant DISTRIBUTOR_CREATOR =
IDistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd);

address public immutable DISTRIBUTOR = DISTRIBUTOR_CREATOR.distributor();
address public immutable FEE_RECIPIENT = DISTRIBUTOR_CREATOR.feeRecipient();
address public immutable RADIANT = VESTING.rdntToken();

// ================================= VARIABLES =================================

Expand All @@ -56,41 +43,22 @@ contract RadiantCoupon is UUPSHelper, ERC20Upgradeable {

// ================================= FUNCTIONS =================================

function token() public view virtual returns (address);

function isTokenWrapper() external pure returns (bool) {
return true;
}

function initialize(ICore _core) public initializer onlyProxy {
__ERC20_init("RadiantCoupon", "cpRDNT");
__ERC20_init(
string.concat("Merkl Token Wrapper - ", IERC20Metadata(token()).name()),
string.concat("mtw", IERC20Metadata(token()).symbol())
);
__UUPSUpgradeable_init();
if (address(_core) == address(0)) revert ZeroAddress();
core = _core;
}

function _beforeTokenTransfer(address from, address to, uint256 amount) internal override {
// Needs an RDNT approval beforehand, this is how mints of coupons are done
if (to == DISTRIBUTOR) {
IERC20(RADIANT).safeTransferFrom(from, address(this), amount);
_mint(from, amount); // These are then transfered to the distributor
}

// Will be burn right after, to avoid having any token aside from on the distributor
if (to == FEE_RECIPIENT) {
IERC20(RADIANT).safeTransferFrom(from, FEE_RECIPIENT, amount);
_mint(from, amount); // These are then transferred to the fee manager
}
}

function _afterTokenTransfer(address from, address to, uint256 amount) internal override {
if (to == FEE_RECIPIENT) {
_burn(to, amount); // To avoid having any token aside from on the distributor
}

if (from == DISTRIBUTOR) {
_burn(to, amount);

// Vesting logic
IERC20(RADIANT).transfer(address(VESTING), amount);
VESTING.vestTokens(to, amount, true);
}
}

/// @notice Recovers any ERC20 token
/// @dev Governance only, to trigger only if something went wrong
function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {
Expand Down
63 changes: 63 additions & 0 deletions contracts/tokenWrappers/RadiantTokenWrapper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.17;

import { ERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

import { BaseMerklTokenWrapper } from "./BaseTokenWrapper.sol";

interface IVesting {
function rdntToken() external view returns (address);
function vestTokens(address, uint256, bool) external returns (address);

Check failure on line 13 in contracts/tokenWrappers/RadiantTokenWrapper.sol

View workflow job for this annotation

GitHub Actions / lint

Insert ⏎
}

/// @title Radiant MTW
/// @dev This token can only be held by merkl distributor
/// @dev Transferring to the distributor will require transferring the underlying token to this contract
/// @dev Transferring from the distributor will trigger vesting action
/// @dev Transferring token to the distributor is permissionless so anyone could mint this wrapper - the only
/// impact would be to forfeit these tokens
contract RadiantMerklTokenWrapper is BaseMerklTokenWrapper {
using SafeERC20 for IERC20;

// ================================= CONSTANTS =================================

IVesting public constant VESTING = IVesting(0x76ba3eC5f5adBf1C58c91e86502232317EeA72dE);
address internal immutable _UNDERLYING = VESTING.rdntToken();

// ================================= FUNCTIONS =================================

function token() public view override returns (address) {
return _UNDERLYING;
}

function _beforeTokenTransfer(address from, address to, uint256 amount) internal override {
// Needs an RDNT approval beforehand, this is how mints of coupons are done
if (to == DISTRIBUTOR) {
IERC20(_UNDERLYING).safeTransferFrom(from, address(this), amount);
_mint(from, amount); // These are then transfered to the distributor
}

// Will be burn right after, to avoid having any token aside from on the distributor
if (to == FEE_RECIPIENT) {
IERC20(_UNDERLYING).safeTransferFrom(from, FEE_RECIPIENT, amount);
_mint(from, amount); // These are then transferred to the fee manager
}
}

function _afterTokenTransfer(address from, address to, uint256 amount) internal override {
if (to == FEE_RECIPIENT) {
_burn(to, amount); // To avoid having any token aside from on the distributor
}

if (from == DISTRIBUTOR) {
_burn(to, amount);

// Vesting logic
IERC20(_UNDERLYING).transfer(address(VESTING), amount);
VESTING.vestTokens(to, amount, true);
}
}
}
File renamed without changes.
4 changes: 2 additions & 2 deletions deploy/coupon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const func: DeployFunction = async ({ deployments, ethers, network }) => {
const { deploy } = deployments;
const { deployer } = await ethers.getNamedSigners();

const couponName = 'RadiantCoupon';
const couponName = 'RadiantMerklTokenWrapper';
const distributionCreator = DistributionCreator__factory.connect('0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd', deployer)
const core = await distributionCreator.core()

Expand Down Expand Up @@ -40,5 +40,5 @@ const func: DeployFunction = async ({ deployments, ethers, network }) => {
console.log('');
};

func.tags = ['coupon'];
func.tags = ['mtw'];
export default func;
Loading

0 comments on commit 487d2f8

Please sign in to comment.