Skip to content

Instantly share code, notes, and snippets.

@petejkim
Created April 27, 2024 16:34
Show Gist options
  • Save petejkim/c0f7d7a7cc4811ec812e113b45c8739e to your computer and use it in GitHub Desktop.
Save petejkim/c0f7d7a7cc4811ec812e113b45c8739e to your computer and use it in GitHub Desktop.
PolygonVotes.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
interface StakeManager {
function currentValidatorSetSize() external view returns (uint256);
function NFTCounter() external view returns (uint256);
function getValidatorContract(uint256 validatorId) external view returns (address);
}
contract PolygonVotes is IERC20 {
error Disabled();
StakeManager public STAKE_MANAGER = StakeManager(0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908);
/// @dev returns total number of matic tokens staked via delegation, meant for offchain use-cases
function totalSupply() external view returns (uint256) {
uint256 valCount = STAKE_MANAGER.NFTCounter();
uint256 totalShares = 0;
for (uint256 i = 1; i <= valCount;) {
address vs = STAKE_MANAGER.getValidatorContract(i);
if (address(vs) != address(0)) {
uint256 supply = IERC20(vs).totalSupply();
if (supply != 0) {
unchecked { totalShares += supply; } // overflow is not a concern
}
}
unchecked { i++; }
}
return totalShares;
}
/// @dev returns the number of matic tokens staked via delegation by an address, meant for offchain use-cases
function balanceOf(address account) external view returns (uint256) {
uint256 valCount = STAKE_MANAGER.NFTCounter();
uint256 shares = 0;
for (uint256 i = 1; i <= valCount;) {
IERC20 vs = IERC20(STAKE_MANAGER.getValidatorContract(i));
if (address(vs) != address(0)) {
uint256 bal = vs.balanceOf(account);
if (bal != 0) {
unchecked { shares += bal; }
}
}
unchecked { i++; }
}
return shares;
}
function name() external pure returns (string memory) {
return "PolygonVotes";
}
function symbol() external pure returns (string memory) {
return "MATICV";
}
function decimals() external pure returns (uint8) {
return 18;
}
function transfer(address to, uint256 value) external pure returns (bool) {
revert Disabled();
}
function allowance(address owner, address spender) external pure returns (uint256) {
return 0;
}
function approve(address spender, uint256 value) external pure returns (bool) {
revert Disabled();
}
function transferFrom(address from, address to, uint256 value) external pure returns (bool) {
revert Disabled();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment