-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update upgradeables, deployed MintyBurnyRegistry,HotDog, and ChillyDog.
- Loading branch information
1 parent
5b88dfe
commit 0ef85ee
Showing
35 changed files
with
2,469 additions
and
151 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 |
---|---|---|
|
@@ -45,6 +45,5 @@ | |
"lint-staged": "~13.2.2", | ||
"next": "~14.0.4", | ||
"vercel": "~32.4.1" | ||
}, | ||
"packageManager": "[email protected]" | ||
} | ||
} |
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,133 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.25; | ||
|
||
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import {ERC20Burnable} from | ||
"@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; | ||
import {IMultiTokenBurnRegistry} from "./common/IMultiTokenBurnRegistry.sol"; | ||
import {IMultiTokenMintRegistry} from "./common/IMultiTokenMintRegistry.sol"; | ||
import {IERC20CustomErrors} from "./ERC20/extensions/IERC20CustomErrors.sol"; | ||
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import "./ERC20/extensions/ERC20ProofOfMint.sol"; | ||
|
||
/// @title An ERC20 token supporting an external registry. | ||
/// @author BillSchumacher | ||
/// @custom:security-contact [email protected] | ||
contract ChillyDog is ERC20, Ownable, ERC20ProofOfMint, ERC20Burnable { | ||
address private _registry; | ||
uint256 private _lastFee; | ||
uint256 private _zeroAddress; | ||
uint256 private _mintFee = 0.01 ether; | ||
string private _description; | ||
|
||
error InsufficientMintFee(uint256 mintFee, uint256 msgValue); | ||
|
||
constructor( | ||
address registry_, | ||
address[] memory contractAddresses | ||
) | ||
ERC20("Chilly Dog", "BRRRR") | ||
Ownable(msg.sender) | ||
ERC20ProofOfMint(contractAddresses) | ||
{ | ||
_registry = registry_; | ||
} | ||
|
||
/// @inheritdoc ERC20 | ||
function balanceOf(address account) | ||
public | ||
view | ||
virtual | ||
override | ||
returns (uint256) | ||
{ | ||
if (account == address(0)) return _zeroAddress; | ||
return ERC20.balanceOf(account); | ||
} | ||
|
||
/// @notice Get the description of the token. | ||
/// @dev Returns the description of the token. | ||
/// @return (string) - the description of the token. | ||
function description() public view returns (string memory) { | ||
return _description; | ||
} | ||
|
||
/// @notice Set the description of the token. | ||
/// @dev Set the description of the token. | ||
/// @param desc (string) - the description of the token. | ||
function setDesc(string calldata desc) public onlyOwner { | ||
_description = desc; | ||
} | ||
|
||
/// @inheritdoc ERC20 | ||
function _update( | ||
address from, | ||
address to, | ||
uint256 value | ||
) internal virtual override(ERC20) { | ||
ERC20._update(from, to, value); | ||
if (to == address(0)) { | ||
_zeroAddress += value; | ||
this._updateBurnRegistry(from, value); | ||
} | ||
if (from == address(0)) { | ||
this._updateMintRegistry(to, value); | ||
} | ||
} | ||
|
||
/// @notice Get the current fee to mint tokens. | ||
/// @dev Returns the current fee to mint tokens. | ||
/// @return (uint256) - the current fee to mint tokens. | ||
function getMintFee() public view returns (uint256) { | ||
return _mintFee; | ||
} | ||
|
||
/// @inheritdoc ERC20ProofOfMint | ||
function beforeMintMinted( | ||
address sender, | ||
address account | ||
) internal override { | ||
uint256 currentMintFee = _mintFee; | ||
uint256 sentValue = msg.value; | ||
if (sentValue < currentMintFee) { | ||
revert InsufficientMintFee(currentMintFee, sentValue); | ||
} | ||
_mintFee = currentMintFee * 1001 / 1000; | ||
sender; | ||
account; | ||
} | ||
|
||
/// @dev Update the burn registry. | ||
/// @param account (address) - the address of the account. | ||
/// @param value (uint256) - the amount of tokens to burn.beforeMintMintedbeforeMintMinted | ||
function _updateBurnRegistry(address account, uint256 value) external { | ||
if (msg.sender != address(this)) { | ||
revert OwnableUnauthorizedAccount(msg.sender); | ||
} | ||
//_registry.call(abi.encodeWithSignature("updateBurnRegistry(address,uint256)", account, value)); | ||
IMultiTokenBurnRegistry(_registry).updateBurnRegistry(account, value); | ||
} | ||
|
||
/// @dev Update the mint registry. | ||
/// @param account (address) - the address of the account. | ||
/// @param value (uint256) - the amount of tokens to mint. | ||
function _updateMintRegistry(address account, uint256 value) external { | ||
if (msg.sender != address(this)) { | ||
revert OwnableUnauthorizedAccount(msg.sender); | ||
} | ||
//_registry.call(abi.encodeWithSignature("updateMintRegistry(address,uint256)", account, value)); | ||
IMultiTokenMintRegistry(_registry).updateMintRegistry(account, value); | ||
} | ||
|
||
/// @notice Allows the token to receive ether. | ||
receive() external payable {} | ||
|
||
/// @notice Allows the token to withdraw ether. | ||
/// @dev Allows the token to withdraw ether. | ||
function withdraw() public onlyOwner { | ||
uint256 value = address(this).balance; | ||
address to = owner(); | ||
(bool success,) = to.call{value: value}(""); | ||
if (!success) revert IERC20CustomErrors.ERC20TransferFailed(to, value); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
packages/foundry/contracts/token/ERC20/extensions/ERC20ExternalBurnRegistry.sol
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,23 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.25; | ||
|
||
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import {Context} from "@openzeppelin/contracts/utils/Context.sol"; | ||
|
||
/// @title An extension to support an external burning registry. | ||
/// @author BillSchumacher | ||
/// @custom:security-contact [email protected] | ||
abstract contract ERC20ExternalBurnRegistry is Context, ERC20 { | ||
address internal _burnRegistry; | ||
|
||
constructor(address memory burnRegistry_) { | ||
_burnRegistry = burnRegistry_; | ||
} | ||
|
||
/// @notice Get the burn registry address. | ||
/// @dev Returns the burn registry address. | ||
/// @return (address) - the burn registry address. | ||
function burnRegistry() public view returns (address) { | ||
return _burnRegistry; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
packages/foundry/contracts/token/ERC20/extensions/ERC20ExternalMintRegistry.sol
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,23 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.25; | ||
|
||
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import {Context} from "@openzeppelin/contracts/utils/Context.sol"; | ||
|
||
/// @title An extension to support an external minting registry. | ||
/// @author BillSchumacher | ||
/// @custom:security-contact [email protected] | ||
abstract contract ERC20ExternalMintRegistry is Context, ERC20 { | ||
address internal _mintRegistry; | ||
|
||
constructor(address memory mintRegistry_) { | ||
_mintRegistry = mintRegistry_; | ||
} | ||
|
||
/// @notice Get the mint registry address. | ||
/// @dev Returns the mint registry address. | ||
/// @return (address) - the mint registry address. | ||
function mintRegistry() public view returns (address) { | ||
return _mintRegistry; | ||
} | ||
} |
144 changes: 144 additions & 0 deletions
144
packages/foundry/contracts/token/ERC20/extensions/ERC20ProofOfRegistryBurner.sol
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,144 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity 0.8.25; | ||
|
||
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import {Context} from "@openzeppelin/contracts/utils/Context.sol"; | ||
import {NoTokensToMint} from "./ERC20MintyBurnyErrors.sol"; | ||
import {ERC20ExternalBurnRegistry} from "./ERC20ExternalBurnRegistry.sol"; | ||
import {IMultiTokenBurnRegistry} from "./common/IMultiTokenBurnRegistry.sol"; | ||
|
||
/// @title A smart contract that checks for burned tokens and mints new tokens based on the burned tokens. | ||
/// @custom:requires burnerContracts to implement ERC20BurnRegistry | ||
/// @author BillSchumacher | ||
/// @custom:security-contact [email protected] | ||
abstract contract ERC20ProofOfRegistryBurner is | ||
Context, | ||
ERC20, | ||
ERC20ExternalBurnRegistry | ||
{ | ||
mapping(address => uint256) private _lastBurnerBurned; | ||
address[] internal _burnerContracts; | ||
|
||
constructor(address[] memory burnerContracts) { | ||
_burnerContracts = burnerContracts; | ||
} | ||
|
||
/// @notice Get the last amount of tokens that were burned. | ||
/// @dev Returns the last amount of tokens that were burned. | ||
/// @return (uint256) - the last amount of tokens that were burned. | ||
function lastBurnerBurned() public view returns (uint256) { | ||
return _lastBurnerBurned[_msgSender()]; | ||
} | ||
|
||
/// @dev Set the last amount of tokens that were burned. Override to customize. | ||
/// @param value (uint256) - the last amount of tokens that were burned. | ||
function setLastBurnerBurned(uint256 value) internal virtual { | ||
_lastBurnerBurned[_msgSender()] = value; | ||
} | ||
|
||
/// @notice Get the amount of tokens eligible to be minted. | ||
/// @dev Returns the amount of tokens eligible to be minted. | ||
/// @return balance (uint256) - the amount of tokens eligible to be minted. | ||
function getCurrentBurnerBurned() | ||
public | ||
payable | ||
virtual | ||
returns (uint256 balance) | ||
{ | ||
address[] memory eligibleBurnerContracts = _burnerContracts; | ||
uint256 contractLength = eligibleBurnerContracts.length; | ||
address sender = _msgSender(); | ||
IMultiTokenBurnRegistry registryContract = | ||
IMultiTokenBurnRegistry(_burnRegistry); | ||
for (uint256 i; i < contractLength;) { | ||
balance += | ||
registryContract.burnedFrom(eligibleBurnerContracts[i], sender); | ||
unchecked { | ||
++i; | ||
} | ||
} | ||
return balance; | ||
} | ||
|
||
/// @notice Get the ratio of tokens to mint. | ||
/// @dev Returns the ratio of tokens to mint. Override to customize. Divided by 10000. 5000 = 0.5 (default) | ||
/// @return (uint256) - the ratio of tokens to mint. | ||
function mintRatio() public pure virtual returns (uint256) { | ||
return 5000; | ||
} | ||
|
||
/// @notice Get the ratio of tokens to mint for ProofOfBurner. | ||
/// @dev Returns the ratio of tokens to mint for ProofOfBurner. Override to customize. Divided by 10000. 5000 = 0.5 (default) | ||
/// @return (uint256) - the ratio of tokens to mint. | ||
function mintBurnerRatio() public view virtual returns (uint256) { | ||
return mintRatio(); | ||
} | ||
|
||
/// @dev Handle access control, accounting, and any conditions here before minting, revert if failed. | ||
/// @param sender (address) - the address of the sender. | ||
/// @param account (address) - the address of the account. | ||
function beforeMintBurnerBurned( | ||
address sender, | ||
address account | ||
) internal virtual {} | ||
|
||
/// @dev Update the mint registry or perform other accounting. Override to customize. | ||
/// @param account (address) - the address of the account. | ||
/// @param value (uint256) - the amount of tokens minted. | ||
function afterMintBurnerBurned( | ||
address account, | ||
uint256 value | ||
) internal virtual {} | ||
|
||
/// @dev Mints the burned tokens for the configured contracts and addresses. | ||
/// @param account (address) - the address of the account. | ||
/// @return (uint256) - the amount of tokens minted. | ||
function _doMintBurnerBurned(address account) | ||
internal | ||
virtual | ||
returns (uint256) | ||
{ | ||
uint256 balance = getCurrentBurnerBurned(); | ||
uint256 tokensLastBurned = lastBurnerBurned(); | ||
if (balance <= tokensLastBurned) { | ||
revert NoTokensToMint(); | ||
} | ||
uint256 tokens = | ||
(balance - tokensLastBurned) * mintBurnerRatio() / 10000; | ||
setLastBurnerBurned(balance); | ||
_mint(account, tokens); | ||
return tokens; | ||
} | ||
|
||
/// @notice Mints the burned tokens for the configured contracts and burner. | ||
/// @dev Mints the burned tokens for the configured contracts and burner. | ||
/// @return tokens (uint256) - the amount of tokens minted. | ||
function mintBurnerBurned() | ||
public | ||
payable | ||
virtual | ||
returns (uint256 tokens) | ||
{ | ||
address sender = _msgSender(); | ||
beforeMintBurnerBurned(sender, sender); | ||
tokens = _doMintBurnerBurned(sender); | ||
afterMintBurnerBurned(sender, tokens); | ||
return tokens; | ||
} | ||
|
||
/// @notice Mints the burned tokens for the configured contracts and burner. | ||
/// @dev Mints the burned tokens for the configured contracts and burner. | ||
/// @return tokens (uint256) - the amount of tokens minted. | ||
function mintBurnerBurnedFor(address account) | ||
public | ||
payable | ||
virtual | ||
returns (uint256 tokens) | ||
{ | ||
address sender = _msgSender(); | ||
beforeMintBurnerBurned(sender, account); | ||
tokens = _doMintBurnerBurned(account); | ||
afterMintBurnerBurned(account, tokens); | ||
return tokens; | ||
} | ||
} |
Oops, something went wrong.