文件 1 的 7:ERC20.sol
pragma solidity >=0.8;
import "./IERC20.sol";
import "./IERC677Receiver.sol";
abstract contract ERC20 is IERC20 {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
uint8 public override decimals;
constructor(uint8 _decimals) {
decimals = _decimals;
}
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(address owner, address spender) public view override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 value) public override returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][msg.sender];
if (currentAllowance < (1 << 255)){
_approve(sender, msg.sender, currentAllowance - amount);
}
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(recipient != address(0));
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] -= amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
function transferAndCall(address recipient, uint amount, bytes calldata data) public returns (bool) {
bool success = transfer(recipient, amount);
if (success){
success = IERC677Receiver(recipient).onTokenTransfer(msg.sender, amount, data);
}
return success;
}
function _mint(address recipient, uint256 amount) internal virtual {
require(recipient != address(0));
_beforeTokenTransfer(address(0), recipient, amount);
_totalSupply += amount;
_balances[recipient] += amount;
emit Transfer(address(0), recipient, amount);
}
function _burn(address account, uint256 amount) internal virtual {
_beforeTokenTransfer(account, address(0), amount);
_totalSupply -= amount;
_balances[account] -= amount;
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 value) internal {
_allowances[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _beforeTokenTransfer(address from, address to, uint256 amount) virtual internal;
}
文件 2 的 7:ERC20Recoverable.sol
pragma solidity >=0.8;
import "./ERC20.sol";
import "./IERC20.sol";
abstract contract ERC20Recoverable is ERC20 {
struct Claim {
address claimant;
uint256 collateral;
uint256 timestamp;
address currencyUsed;
}
uint256 public constant claimPeriod = 180 days;
mapping(address => Claim) public claims;
mapping(address => bool) public recoveryDisabled;
address public customCollateralAddress;
uint256 public customCollateralRate;
function getCollateralRate(address collateralType) public virtual view returns (uint256) {
if (collateralType == address(this)) {
return 1;
} else if (collateralType == customCollateralAddress) {
return customCollateralRate;
} else {
return 0;
}
}
function _setCustomClaimCollateral(address collateral, uint256 rate) internal {
customCollateralAddress = collateral;
if (customCollateralAddress == address(0)) {
customCollateralRate = 0;
} else {
require(rate > 0, "Collateral rate can't be zero");
customCollateralRate = rate;
}
emit CustomClaimCollateralChanged(collateral, rate);
}
function getClaimDeleter() virtual public view returns (address);
function setRecoverable(bool enabled) public {
recoveryDisabled[msg.sender] = !enabled;
}
function isRecoveryEnabled(address target) public view returns (bool) {
return !recoveryDisabled[target];
}
event ClaimMade(address indexed lostAddress, address indexed claimant, uint256 balance);
event ClaimCleared(address indexed lostAddress, uint256 collateral);
event ClaimDeleted(address indexed lostAddress, address indexed claimant, uint256 collateral);
event ClaimResolved(address indexed lostAddress, address indexed claimant, uint256 collateral);
event CustomClaimCollateralChanged(address newCustomCollateralAddress, uint256 newCustomCollareralRate);
function declareLost(address collateralType, address lostAddress) public {
require(isRecoveryEnabled(lostAddress), "Claims disabled for this address");
uint256 collateralRate = getCollateralRate(collateralType);
require(collateralRate > 0, "Unsupported collateral");
address claimant = msg.sender;
uint256 balance = balanceOf(lostAddress);
uint256 collateral = balance * collateralRate;
IERC20 currency = IERC20(collateralType);
require(balance > 0, "Claimed address holds no shares");
require(claims[lostAddress].collateral == 0, "Address already claimed");
require(currency.transferFrom(claimant, address(this), collateral), "Collateral transfer failed");
claims[lostAddress] = Claim({
claimant: claimant,
collateral: collateral,
timestamp: block.timestamp,
currencyUsed: collateralType
});
emit ClaimMade(lostAddress, claimant, balance);
}
function getClaimant(address lostAddress) public view returns (address) {
return claims[lostAddress].claimant;
}
function getCollateral(address lostAddress) public view returns (uint256) {
return claims[lostAddress].collateral;
}
function getCollateralType(address lostAddress) public view returns (address) {
return claims[lostAddress].currencyUsed;
}
function getTimeStamp(address lostAddress) public view returns (uint256) {
return claims[lostAddress].timestamp;
}
function transfer(address recipient, uint256 amount) override virtual public returns (bool) {
require(super.transfer(recipient, amount), "Transfer failed");
clearClaim();
return true;
}
function clearClaim() public {
if (claims[msg.sender].collateral != 0) {
uint256 collateral = claims[msg.sender].collateral;
IERC20 currency = IERC20(claims[msg.sender].currencyUsed);
delete claims[msg.sender];
require(currency.transfer(msg.sender, collateral), "Collateral transfer failed");
emit ClaimCleared(msg.sender, collateral);
}
}
function recover(address lostAddress) public {
Claim memory claim = claims[lostAddress];
uint256 collateral = claim.collateral;
IERC20 currency = IERC20(claim.currencyUsed);
require(collateral != 0, "No claim found");
require(claim.claimant == msg.sender, "Only claimant can resolve claim");
require(claim.timestamp + claimPeriod <= block.timestamp, "Claim period not over yet");
address claimant = claim.claimant;
delete claims[lostAddress];
require(currency.transfer(claimant, collateral), "Collateral transfer failed");
_transfer(lostAddress, claimant, balanceOf(lostAddress));
emit ClaimResolved(lostAddress, claimant, collateral);
}
function deleteClaim(address lostAddress) public {
require(msg.sender == getClaimDeleter(), "You cannot delete claims");
Claim memory claim = claims[lostAddress];
IERC20 currency = IERC20(claim.currencyUsed);
require(claim.collateral != 0, "No claim found");
delete claims[lostAddress];
require(currency.transfer(claim.claimant, claim.collateral), "Collateral transfer failed");
emit ClaimDeleted(lostAddress, claim.claimant, claim.collateral);
}
}
文件 3 的 7:IERC20.sol
pragma solidity >=0.8;
interface IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 4 的 7:IERC677Receiver.sol
pragma solidity >=0.8;
interface IERC677Receiver {
function onTokenTransfer(address from, uint256 amount, bytes calldata data) external returns (bool);
}
文件 5 的 7:Ownable.sol
pragma solidity >=0.8;
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
owner = msg.sender;
emit OwnershipTransferred(address(0), owner);
}
modifier onlyOwner() {
require(owner == msg.sender, "not owner");
_;
}
function transferOwnership(address newOwner) public onlyOwner {
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
文件 6 的 7:Shares.sol
pragma solidity >=0.8;
import "./Ownable.sol";
import "./ERC20Recoverable.sol";
import "./IERC677Receiver.sol";
contract Shares is ERC20Recoverable, Ownable {
string public override name;
string public override symbol;
string public terms;
uint256 public totalShares = 0;
uint256 public invalidTokens = 0;
address[] public subregisters;
event Announcement(string message);
event TokensDeclaredInvalid(address indexed holder, uint256 amount, string message);
event ShareNumberingEvent(address indexed holder, uint256 firstInclusive, uint256 lastInclusive);
event SubRegisterAdded(address contractAddress);
event SubRegisterRemoved(address contractAddress);
constructor(string memory _symbol, string memory _name, string memory _terms, uint256 _totalShares) ERC20(0) {
setName(_symbol, _name);
setTotalShares(_totalShares);
terms = _terms;
}
function setName(string memory _symbol, string memory _name) public onlyOwner {
symbol = _symbol;
name = _name;
emit Announcement(string(abi.encodePacked("New name: ", _name, " (", _symbol, ")")));
}
function setTerms(string memory _terms) public onlyOwner {
terms = _terms;
emit Announcement(string(abi.encodePacked("New terms: ", _terms)));
}
function setTotalShares(uint256 _newTotalShares) public onlyOwner() {
require(_newTotalShares >= totalValidSupply(), "There can't be fewer tokens than shares");
totalShares = _newTotalShares;
}
function countSubregisters() public view returns (uint256){
return subregisters.length;
}
function recognizeSubRegister(address contractAddress) public onlyOwner () {
require(balanceOf(contractAddress) == 0, "Subregisters must be empty when added");
subregisters.push(contractAddress);
emit SubRegisterAdded(contractAddress);
}
function removeSubRegister(address contractAddress) public onlyOwner() {
require(balanceOf(contractAddress) == 0, "Subregisters must be empty when removed");
for (uint256 i = 0; i<subregisters.length; i++) {
if (subregisters[i] == contractAddress) {
subregisters[i] = subregisters[subregisters.length - 1];
subregisters.pop();
emit SubRegisterRemoved(contractAddress);
}
}
}
function balanceOfDeep(address holder) public view returns (uint256) {
uint256 balance = balanceOf(holder);
for (uint256 i = 0; i<subregisters.length; i++) {
IERC20 subERC = IERC20(subregisters[i]);
balance += subERC.balanceOf(holder);
}
return balance;
}
function announcement(string calldata message) external onlyOwner() {
emit Announcement(message);
}
function setCustomClaimCollateral(address collateral, uint256 rate) public onlyOwner() {
super._setCustomClaimCollateral(collateral, rate);
}
function getClaimDeleter() public override view returns (address) {
return owner;
}
function declareInvalid(address holder, uint256 amount, string calldata message) external onlyOwner() {
uint256 holderBalance = balanceOf(holder);
require(amount <= holderBalance);
invalidTokens += amount;
emit TokensDeclaredInvalid(holder, amount, message);
}
function totalValidSupply() public view returns (uint256) {
return totalSupply() - invalidTokens;
}
function mint(address shareholder, uint256 _amount) public onlyOwner() {
_mint(shareholder, _amount);
}
function mintAndCall(address shareholder, address callee, uint256 amount, bytes calldata data) public {
mint(callee, amount);
IERC677Receiver(callee).onTokenTransfer(shareholder, amount, data);
}
function mintNumbered(address shareholder, uint256 firstShareNumber, uint256 lastShareNumber) public onlyOwner() {
emit ShareNumberingEvent(shareholder, firstShareNumber, lastShareNumber);
_mint(shareholder, lastShareNumber - firstShareNumber + 1);
}
function mintNumberedAndCall(address shareholder, address callee, uint256 firstShareNumber, uint256 lastShareNumber, bytes calldata data) public {
mintNumbered(shareholder, firstShareNumber, lastShareNumber);
IERC677Receiver(callee).onTokenTransfer(shareholder, lastShareNumber - firstShareNumber + 1, data);
}
function _mint(address account, uint256 amount) internal override {
require(totalValidSupply() + amount <= totalShares, "There can't be fewer shares than valid tokens");
super._mint(account, amount);
}
function burn(uint256 _amount) public {
require(_amount <= balanceOf(msg.sender), "Not enough shares available");
_transfer(msg.sender, address(this), _amount);
_burn(address(this), _amount);
}
function _beforeTokenTransfer(address from, address to, uint256 amount) override internal {
}
}
文件 7 的 7:SharesWithPredecessor.sol
pragma solidity >=0.8;
import "./Shares.sol";
contract SharesWithPredecessor is Shares {
Shares private immutable predecessor;
constructor(address _predecessor, string memory _symbol, string memory _name, string memory _terms, uint256 _totalShares) Shares(_symbol, _name, _terms, _totalShares) {
predecessor = Shares(_predecessor);
}
function convertOldShares() public {
uint256 balance = predecessor.balanceOf(msg.sender);
predecessor.transferFrom(msg.sender, address(this), balance);
predecessor.burn(balance);
_mint(msg.sender, balance);
}
}
{
"compilationTarget": {
"SharesWithPredecessor.sol": "SharesWithPredecessor"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_predecessor","type":"address"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_terms","type":"string"},{"internalType":"uint256","name":"_totalShares","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"Announcement","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lostAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"}],"name":"ClaimCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lostAddress","type":"address"},{"indexed":true,"internalType":"address","name":"claimant","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"}],"name":"ClaimDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lostAddress","type":"address"},{"indexed":true,"internalType":"address","name":"claimant","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"}],"name":"ClaimMade","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lostAddress","type":"address"},{"indexed":true,"internalType":"address","name":"claimant","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateral","type":"uint256"}],"name":"ClaimResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newCustomCollateralAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"newCustomCollareralRate","type":"uint256"}],"name":"CustomClaimCollateralChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":false,"internalType":"uint256","name":"firstInclusive","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastInclusive","type":"uint256"}],"name":"ShareNumberingEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"SubRegisterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"contractAddress","type":"address"}],"name":"SubRegisterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"message","type":"string"}],"name":"TokensDeclaredInvalid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"message","type":"string"}],"name":"announcement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"balanceOfDeep","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claims","outputs":[{"internalType":"address","name":"claimant","type":"address"},{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"address","name":"currencyUsed","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"clearClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"convertOldShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"countSubregisters","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"customCollateralAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"customCollateralRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"string","name":"message","type":"string"}],"name":"declareInvalid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collateralType","type":"address"},{"internalType":"address","name":"lostAddress","type":"address"}],"name":"declareLost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"deleteClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getClaimDeleter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"getClaimant","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"getCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collateralType","type":"address"}],"name":"getCollateralRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"getCollateralType","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"getTimeStamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invalidTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"isRecoveryEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"address","name":"callee","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintAndCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"uint256","name":"firstShareNumber","type":"uint256"},{"internalType":"uint256","name":"lastShareNumber","type":"uint256"}],"name":"mintNumbered","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"address","name":"callee","type":"address"},{"internalType":"uint256","name":"firstShareNumber","type":"uint256"},{"internalType":"uint256","name":"lastShareNumber","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mintNumberedAndCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"recognizeSubRegister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lostAddress","type":"address"}],"name":"recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"recoveryDisabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"removeSubRegister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collateral","type":"address"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setCustomClaimCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setRecoverable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_terms","type":"string"}],"name":"setTerms","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTotalShares","type":"uint256"}],"name":"setTotalShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"subregisters","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"terms","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalValidSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]