Goat27 合约函数文档
Goat27 合约函数文档
本文档列出 src/Goat27/Goat27.sol 中所有外部可调用函数的签名、用途、参数与返回值。
权限说明:OWNER 表示需要 Ownable.onlyOwner;ANYONE 表示任何地址可调用;WHITELISTED 表示买卖税白名单中的地址可被自动豁免(非权限,而是状态查询)。
合约类型:ERC20 + ERC20Permit + Ownable,在 PancakeSwap V2 交易对上自动按 5% 买卖税收取并按 20/80 销毁/兑换 USDT;同时叠加 5%/天的复利通缩。
1. ERC20 标准函数
1.1 name
- 签名:
function name() external view returns (string memory) - 权限:ANYONE
- 用途:返回代币名称,固定为
"GOAT27"。 - 参数:无。
- 返回值:
string memory代币名称。
1.2 symbol
- 签名:
function symbol() external view returns (string memory) - 权限:ANYONE
- 用途:返回代币符号,固定为
"GOAT27"。 - 参数:无。
- 返回值:
string memory代币符号。
1.3 decimals
- 签名:
function decimals() external view returns (uint8) - 权限:ANYONE
- 用途:返回代币精度,固定为
18(在构造函数中硬编码到不可变量_decimals)。 - 参数:无。
- 返回值:
uint8代币精度。
1.4 totalSupply
- 签名:
function totalSupply() external view returns (uint256) - 权限:ANYONE
- 用途:返回代币总供应量。初始供应
1_000_000_000 * 1e18在构造函数中一次性铸造给initialHolder_,之后只有 5% 买卖税会通过销毁逐步减少总量(每次税费分配销毁burnAmount)。 - 参数:无。
- 返回值:
uint256当前总供应量(18 位小数)。
1.5 balanceOf
- 签名:
function balanceOf(address account) external view returns (uint256) - 权限:ANYONE
- 用途:返回指定账户的通缩后余额(实时计算,非 OZ 原生
balanceOf)。 - 参数:
account:要查询的账户地址。
- 返回值:
uint256该账户的当前可用余额(18 位小数)。白名单账户返回_deflation.baseBalance(锁定值);非白名单账户按复利通缩公式折算到当前时间。 - 特殊语义:
_deflation.baseBalance == 0时直接返回 OZ 原生balanceOf(避免对刚 mint 的地址做空折算)。- 白名单账户返回
baseBalance,不随时间衰减。 - 通缩算法:N 天未动的余额衰减为
baseBalance * 0.95^N(复利,不是线性)。任何账户的转账都会立刻折算到当前时间。
1.6 allowance
- 签名:
function allowance(address owner, address spender) external view returns (uint256) - 权限:ANYONE
- 用途:返回
spender对owner的授权额度,语义与标准 ERC20 一致。 - 参数:
owner:被授权人地址。spender:被授权使用方地址。
- 返回值:
uint256当前授权额度。
1.7 transfer
- 签名:
function transfer(address to, uint256 value) external returns (bool) - 权限:ANYONE(可被买卖税自动按比例扣减)
- 用途:转账指定数量的代币。内部调用
_update(from, to, value)。若为买卖转账则按 5% 收税,否则按当前通缩基线扣减。详见_update逻辑。 - 参数:
to:接收方地址,不能为零地址。value:转账数量(18 位小数)。
- 返回值:
bool始终为true(失败会 revert)。 - 错误:
InsufficientBalance(have, want)当from通缩后余额不足,且差额不属于”最近 5 分钟变化量”的白名单区间时抛出。InsufficientOzBalance(have, want)当from是白名单,但 OZ 原生余额不足时抛出。
1.8 approve
- 签名:
function approve(address spender, uint256 value) external returns (bool) - 权限:ANYONE
- 用途:授权
spender最多可使用调用者value数量的代币。语义与标准 ERC20 一致。 - 参数:
spender:被授权方地址。value:授权额度(若要取消授权传0)。
- 返回值:
bool始终为true。 - 事件:
Approval(owner, spender, value)(OZ 标准)。
1.9 transferFrom
- 签名:
function transferFrom(address from, address to, uint256 value) external returns (bool) - 权限:ANYONE(需先被
from通过approve授权) - 用途:由第三方代替
from转账给to,会先扣减授权额度再走_update。 - 参数:
from:代币发送方地址。to:接收方地址。value:转账数量。
- 返回值:
bool始终为true。 - 错误:同
transfer。
1.10 permit
- 签名:
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external - 权限:ANYONE(通过 EIP-2612 离线签名授权)
- 用途:通过签名一次性完成授权,无需先发送
approve交易。来自ERC20Permit。 - 参数:同 EIP-2612 标准。
- 返回值:无。
1.11 nonces
- 签名:
function nonces(address owner) external view returns (uint256) - 权限:ANYONE
- 用途:返回 EIP-2612 permit 防重放序号。
- 参数:
owner:查询的账户地址。
- 返回值:
uint256该账户当前的 permit nonce。
1.12 DOMAIN_SEPARATOR
- 签名:
function DOMAIN_SEPARATOR() external view returns (bytes32) - 权限:ANYONE
- 用途:返回 EIP-712 域分隔符,用于 permit 签名验证。
2. 公共函数(税费分配)
2.1 triggerDistribution
- 签名:
function triggerDistribution() external - 权限:ANYONE
- 用途:手动触发一次税费分配。检查
accumulatedTax,若为 0 则直接返回;否则执行”销毁 20% + 80% 在底池兑换成 USDT + USDT 一半转给lpDividendAddress并触发 LP 池分配 + 另一半转给ecoFundAddress“。整个过程通过whenNotDistributing修饰器串行化。 - 参数:无。
- 返回值:无。
- 错误:
OnlySelf()当合约内_doDistribution被try/catch直接调用时抛出(msg.sender != address(this))。外部调用triggerDistribution不会触发此错误,因为内部通过this._doDistribution()转发。string("distribution in progress")当已有一次分配正在进行时抛出(防御性,正常不应触发)。
3. 管理员函数:地址设置
3.1 setLiquidityPair
- 签名:
function setLiquidityPair(address pair) external - 权限:OWNER
- 用途:设置 PancakeSwap V2 的 GOAT27-USDT 交易对地址。会自动维护
deflationWhitelist:从旧的 Pair 移除白名单,新的 Pair 加入白名单(避免 Pair 自身的余额被通缩)。 - 参数:
pair:新的 Pair 地址,可以为零地址(取消设置)。
- 返回值:无。
- 事件:
LiquidityPairUpdated(previousPair, newPair)。
3.2 setLpDividendAddress
- 签名:
function setLpDividendAddress(address newAddress) external - 权限:OWNER
- 用途:设置 LP 分发地址(典型为
Goat27LPStaking合约)。每次税费分配时,USDT 一半会先转给该地址,然后调用其triggerDistribution。会自动维护deflationWhitelist。 - 参数:
newAddress:新的 LP 分发地址,不能为零地址。
- 返回值:无。
- 错误:
ZeroAddress()当newAddress为零地址时抛出。 - 事件:
LpDividendAddressUpdated(previousAddress, newAddress)。
3.3 setEcoFundAddress
- 签名:
function setEcoFundAddress(address newAddress) external - 权限:OWNER
- 用途:设置生态基金地址。每次税费分配时,USDT 另一半会转给该地址。不能为零地址。
- 参数:
newAddress:新的生态基金地址。
- 返回值:无。
- 错误:
ZeroAddress()当newAddress为零地址时抛出。 - 事件:
EcoFundAddressUpdated(newAddress)。
3.4 setRouter
- 签名:
function setRouter(address newRouter) external - 权限:OWNER
- 用途:更新 PancakeSwap V2 路由合约地址。会自动把旧路由的授权清零(
forceApprove(old, 0)),新路由的授权在下次 swap 时按需给出。 - 参数:
newRouter:新的路由地址,不能为零地址。
- 返回值:无。
- 错误:
ZeroRouterAddress()当newRouter为零地址时抛出。 - 事件:
RouterUpdated(previousRouter, newRouter)。
3.5 setUsdt
- 签名:
function setUsdt(address newUsdt) external - 权限:OWNER
- 用途:更新 USDT 合约地址。仅在 USDT 合约迁移或测试网切换时使用。
- 参数:
newUsdt:新的 USDT 地址,不能为零地址。
- 返回值:无。
- 错误:
ZeroAddress()当newUsdt为零地址时抛出。 - 事件:
UsdtUpdated(previousUsdt, newUsdt)。
4. 管理员函数:白名单
4.1 setTaxWhitelist
- 签名:
function setTaxWhitelist(address account, bool whitelisted) external - 权限:OWNER
- 用途:将指定账户加入或移出”买卖税白名单”。白名单账户之间互相转账不收 5% 税,也不触发对方收税。
- 参数:
account:目标账户地址。whitelisted:true加入,false移除。
- 返回值:无。
- 事件:
TaxWhitelistUpdated(account, whitelisted)。
4.2 setTaxWhitelistBatch
- 签名:
function setTaxWhitelistBatch(address[] calldata accounts, bool whitelisted) external - 权限:OWNER
- 用途:批量设置买卖税白名单。
- 参数:
accounts:目标账户地址数组。whitelisted:统一的目标状态。
- 返回值:无。
- 事件:对每个账户各触发一次
TaxWhitelistUpdated。
4.3 setDeflationWhitelist
- 签名:
function setDeflationWhitelist(address account, bool whitelisted) external - 权限:OWNER
- 用途:将指定账户加入或移出”通缩白名单”。白名单账户的余额按
_deflation.baseBalance锁定,不随时间衰减;首次加入白名单时会将当前余额快照到baseBalance,以确保balanceOf()返回值不变。 - 参数:
account:目标账户地址。whitelisted:目标状态。
- 返回值:无。
- 特殊语义:若
deflationWhitelist[account] == whitelisted(状态未变化)则直接返回,不修改 storage。 - 事件:
DeflationWhitelistUpdated(account, whitelisted)。
4.4 setDeflationWhitelistBatch
- 签名:
function setDeflationWhitelistBatch(address[] calldata accounts, bool whitelisted) external - 权限:OWNER
- 用途:批量设置通缩白名单,跳过状态未变化的账户。
- 参数:
accounts:目标账户地址数组。whitelisted:统一的目标状态。
- 返回值:无。
- 事件:对每个状态实际变化的账户各触发一次
DeflationWhitelistUpdated。
4.5 addToWhitelist
- 签名:
function addToWhitelist(address account) external - 权限:OWNER
- 用途:一次性把指定账户加入”双白名单”(同时加入买卖税白名单与通缩白名单)。幂等:重复调用对 tax whitelist 总是 set true 并 emit 事件;deflation whitelist 若已存在则只 emit 事件,不重写 storage。
- 参数:
account:目标账户地址,不能为零地址。
- 返回值:无。
- 错误:
ZeroAddress()当account为零地址时抛出。 - 事件:
TaxWhitelistUpdated(account, true)+DeflationWhitelistUpdated(account, true)。
4.6 addToWhitelistBatch
- 签名:
function addToWhitelistBatch(address[] calldata accounts) external - 权限:OWNER
- 用途:批量版
addToWhitelist。数组中任一为零地址都会导致整个调用 revert。 - 参数:
accounts:目标账户地址数组。
- 返回值:无。
- 错误:
ZeroAddress()当数组中任一地址为零地址时抛出。
5. 视图函数
5.1 deflationBaseBalance
- 签名:
function deflationBaseBalance(address account) external view returns (uint256) - 权限:ANYONE
- 用途:返回指定账户的通缩基线余额(
_deflation.baseBalance,通缩计算的起点)。非白名单账户的”实际余额”会随时间从该值开始衰减。 - 参数:
account:查询的账户地址。
- 返回值:
uint256基线余额(18 位小数)。
5.2 deflationBaseTime
- 签名:
function deflationBaseTime(address account) external view returns (uint256) - 权限:ANYONE
- 用途:返回指定账户基线余额的更新时间戳(
_deflation.baseUpdateTime),即”通缩从该时间开始计算”的时间点。 - 参数:
account:查询的账户地址。
- 返回值:
uint256基线时间戳(秒)。
5.3 deflationStopTime
- 签名:
function deflationStopTime() external pure returns (uint256) - 权限:ANYONE
- 用途:返回通缩停止时间戳常量
1801843200(2027-02-05 16:00:00 UTC)。超过该时间后,所有账户的余额衰减被冻结在”截至该时间”的值上。 - 返回值:
uint256通缩停止时间戳。
5.4 usdt
- 签名:
function usdt() external view returns (address) - 权限:ANYONE
- 用途:返回当前生效的 USDT 合约地址(从不可变量
_usdt读出)。 - 返回值:
addressUSDT 合约地址。
5.5 blackHole
- 签名:
function blackHole() external pure returns (address) - 权限:ANYONE
- 用途:返回黑洞销毁地址常量
0x000000000000000000000000000000000000dEaD(税费销毁与直推无主奖励的接收方)。 - 返回值:
address黑洞地址。
5.6 usdtForwarder
- 签名:
function usdtForwarder() external view returns (address) - 权限:ANYONE
- 用途:返回部署时自动创建的 USDT 中转合约地址(
USDTForwarder)。该合约用于在税费分配时接收 swap 后的 USDT,再 withdraw 到主合约,从而绕过”to == token0/token1”的 pair mock 限制。 - 返回值:
addressUSDTForwarder 地址。
5.7 liquidityPair
- 签名:
function liquidityPair() external view returns (address) - 权限:ANYONE
- 用途:返回当前设置的 PancakeSwap V2 Pair 地址(可能为零地址,若尚未设置)。
5.8 lpDividendAddress
- 签名:
function lpDividendAddress() external view returns (address) - 权限:ANYONE
- 用途:返回当前设置的 LP 分发地址(可能为零地址)。
5.9 ecoFundAddress
- 签名:
function ecoFundAddress() external view returns (address) - 权限:ANYONE
- 用途:返回当前设置的生态基金地址(可能为零地址)。
5.10 router
- 签名:
function router() external view returns (address) - 权限:ANYONE
- 用途:返回当前设置的 PancakeSwap Router 地址。
5.11 accumulatedTax
- 签名:
function accumulatedTax() external view returns (uint256) - 权限:ANYONE
- 用途:返回当前累计未分配的代币税(每次买卖税 5% 中的 100% 全部累加到此,达到
TAX_THRESHOLD = 10000 * 1e18时自动分配一次)。
5.12 taxWhitelist
- 签名:
function taxWhitelist(address account) external view returns (bool) - 权限:ANYONE
- 用途:查询指定账户是否在买卖税白名单中(白名单内买卖免 5% 税)。
5.13 deflationWhitelist
- 签名:
function deflationWhitelist(address account) external view returns (bool) - 权限:ANYONE
- 用途:查询指定账户是否在通缩白名单中(白名单余额不衰减)。
6. Ownable 标准函数
合约使用 OpenZeppelin Ownable,提供以下标准接口(节选):
| 函数 | 签名 | 说明 |
|---|---|---|
owner |
function owner() external view returns (address) |
当前合约所有者 |
transferOwnership |
function transferOwnership(address newOwner) external |
发起所有权转移(仅 owner) |
renounceOwnership |
function renounceOwnership() external |
放弃所有权(仅 owner) |
7. 事件索引
| 事件 | 签名 | 触发时机 |
|---|---|---|
LiquidityPairUpdated |
event LiquidityPairUpdated(address indexed previousPair, address indexed newPair) |
Pair 地址更新 |
LpDividendAddressUpdated |
event LpDividendAddressUpdated(address indexed previousAddress, address indexed newAddress) |
LP 分发地址更新 |
EcoFundAddressUpdated |
event EcoFundAddressUpdated(address indexed newAddress) |
生态基金地址更新 |
RouterUpdated |
event RouterUpdated(address indexed previousRouter, address indexed newRouter) |
路由地址更新 |
UsdtUpdated |
event UsdtUpdated(address indexed previousUsdt, address indexed newUsdt) |
USDT 地址更新 |
TaxWhitelistUpdated |
event TaxWhitelistUpdated(address indexed account, bool whitelisted) |
买卖税白名单变更 |
DeflationWhitelistUpdated |
event DeflationWhitelistUpdated(address indexed account, bool whitelisted) |
通缩白名单变更 |
TaxDistributed |
event TaxDistributed(uint256 burnAmount, uint256 swapAmount, uint256 usdtReceived) |
税费分配完成(每次成功执行 _doDistribution 时触发) |
Transfer |
event Transfer(address indexed from, address indexed to, uint256 value) |
转账(来自 OZ ERC20) |
Approval |
event Approval(address indexed owner, address indexed spender, uint256 value) |
授权(来自 OZ ERC20) |
8. 错误索引
| 错误 | 触发条件 |
|---|---|
ZeroAddress() |
关键参数为零地址(适用于 setLpDividendAddress / setEcoFundAddress / setUsdt / addToWhitelist 等) |
ZeroUsdtAddress() |
构造函数中 usdt_ 为零地址 |
ZeroRouterAddress() |
构造函数中或 setRouter 时 newRouter 为零地址 |
LiquidityPairNotSet() |
发生买卖时 liquidityPair == 0 |
LpDividendAddressNotSet() |
发生买卖时 lpDividendAddress == 0 |
InsufficientBalance(have, want) |
非白名单账户的通缩后余额不足 |
InsufficientOzBalance(have, want) |
白名单账户的 OZ 原生余额不足 |
OnlySelf() |
内部 _doDistribution 被以 address(this) 之外的身份直接调用 |
9. 通缩模型示例
合约采用复利通缩:每天对当前余额减少 5%,N 天后余额为 baseBalance * 0.95^N。每一天内部又按 288 个 5 分钟周期线性分布。
假设 Alice 的基线余额 baseBalance = 1000 GOAT27,已 5 天未动:
| 时间(UTC) | 累计天数 | 当前余额(估算) |
|---|---|---|
| T0 | 0 | 1000.00 |
| T0 + 1 day | 1 | 950.00 |
| T0 + 2 day | 2 | 902.50 |
| T0 + 5 day | 5 | 773.78 |
| 2027-02-05 16:00 UTC 后 | 冻结 | 不再衰减(按 2027-02-05 16:00 UTC 时刻余额锁定) |
注意:即使超过
deflationStopTime,所有非白名单账户的余额仍会持续更新,但衰减上限被钉死在 2027-02-05 16:00 UTC 时刻的余额;之后任何转账、查询都会使用这个冻结值。
10. 税费分配流程
每次 accumulatedTax >= TAX_THRESHOLD (10000 * 1e18) 触发一次自动分配,或在阈值未达时任何人可手动调用 triggerDistribution()。单次分配流程:
1 | accumulatedTax(假设 X) |
原子性:USDT 转账与
lpDividendAddress.triggerDistribution必须在同一交易中全部成功;任一失败会导致整个_doDistribution回退(USDT 转账、burnAmount销毁、accumulatedTax 清零均撤销)。
11. 买/卖自动税流程
当 from == liquidityPair 时判定为买入;to == liquidityPair 时判定为卖出。两者均不在白名单时:
1 | 用户发起 transfer/transferFrom |
注意:自动分配走
try/catch,即使分配失败也不会影响本次转账;但triggerDistribution()直接调用时失败会回退调用者整个交易。