76 lines
2.2 KiB
Solidity
76 lines
2.2 KiB
Solidity
// SPDX-License-Identifier: CC0-1.0
|
|
pragma solidity ^0.8.2;
|
|
|
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
|
|
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
|
|
import "@openzeppelin/contracts/governance/Governor.sol";
|
|
import "../interfaces/IInfluencer.sol";
|
|
import "../interfaces/IABT.sol";
|
|
|
|
contract MyToken is ERC20, ERC20Permit, ERC20Votes, Governor {
|
|
constructor() ERC20("GovToken", "GOV") ERC20Permit("Governance Token") {}
|
|
|
|
mapping(address => uint256[]) private _multiplier;
|
|
address public influencer;
|
|
|
|
// The functions below are overrides required by Solidity.
|
|
|
|
function _afterTokenTransfer(
|
|
address from,
|
|
address to,
|
|
uint256 amount
|
|
) internal override(ERC20, ERC20Votes) {
|
|
super._afterTokenTransfer(from, to, amount);
|
|
}
|
|
|
|
function _mint(address to, uint256 amount)
|
|
internal
|
|
override(ERC20, ERC20Votes)
|
|
{
|
|
super._mint(to, amount);
|
|
}
|
|
|
|
function _burn(address account, uint256 amount)
|
|
internal
|
|
override(ERC20, ERC20Votes)
|
|
{
|
|
super._burn(account, amount);
|
|
}
|
|
|
|
function _sqrt(uint256 x) internal returns (uint256 y) {
|
|
uint256 z = (x + 1) / 2;
|
|
y = x;
|
|
while (z < y) {
|
|
y = z;
|
|
z = (x / z + z) / 2;
|
|
}
|
|
}
|
|
|
|
function getVotes(address account)
|
|
public
|
|
view
|
|
virtual
|
|
override
|
|
returns (uint256)
|
|
{
|
|
uint256 pos = _checkpoints[account].length;
|
|
uint256 vote = pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
|
|
// 0 as None, Multiplied with
|
|
uint256 multiplied = _multiplier[pos - 1] > 0
|
|
? _sqrt(vote)
|
|
: _sqrt(vote * _multiplier[pos - 1]);
|
|
return multiplied;
|
|
}
|
|
|
|
function mulInfluence(address abt, uint256 id) public {
|
|
require(IABT(abt).ownerOf(id) == msg.sender, "Vote: not abt owner");
|
|
uint256 pos = _checkpoints[msg.sender].length;
|
|
_multiplier[pos - 1] = IInfluencer.getInfluence(abt, id);
|
|
}
|
|
|
|
function setInfluencer(address influencer_) public onlyGovernance {
|
|
influencer = influencer_;
|
|
}
|
|
}
|