Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Vyper",
"sources": {
".venv/lib/pypy3.11/site-packages/snekmate/auth/ownable.vy": {
"content": "# pragma version ~=0.4.3
# pragma nonreentrancy off
"""
@title Owner-Based Access Control Functions
@custom:contract-name ownable
@license GNU Affero General Public License v3.0 only
@author pcaversaccio
@notice These functions can be used to implement a basic access
control mechanism, where there is an account (an owner)
that can be granted exclusive access to specific functions.
By default, the owner account will be the one that deploys
the contract. This can later be changed with `transfer_ownership`.
An exemplary integration can be found in the ERC-20 implementation here:
https://github.com/pcaversaccio/snekmate/blob/main/src/snekmate/tokens/erc20.vy.
The implementation is inspired by OpenZeppelin's implementation here:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol.
"""
# @dev Returns the address of the current owner.
# @notice If you declare a variable as `public`,
# Vyper automatically generates an `external`
# getter function for the variable.
owner: public(address)
# @dev Emitted when the ownership is transferred
# from `previous_owner` to `new_owner`.
event OwnershipTransferred:
previous_owner: indexed(address)
new_owner: indexed(address)
@deploy
@payable
def __init__():
"""
@dev To omit the opcodes for checking the `msg.value`
in the creation-time EVM bytecode, the constructor
is declared as `payable`.
@notice The `owner` role will be assigned to
the `msg.sender`.
"""
self._transfer_ownership(msg.sender)
@external
def transfer_ownership(new_owner: address):
"""
@dev Transfers the ownership of the contract
to a new account `new_owner`.
@notice Note that this function can only be
called by the current `owner`. Also,
the `new_owner` cannot be the zero address.
@param new_owner The 20-byte address of the new owner.
"""
self._check_owner()
assert new_owner != empty(address), "ownable: new owner is the zero address"
self._transfer_ownership(new_owner)
@external
def renounce_ownership():
"""
@dev Leaves the contract without an owner.
@notice Renouncing ownership will leave the
contract without an owner, thereby
removing any functionality that is
only available to the owner.
"""
self._check_owner()
self._transfer_ownership(empty(address))
@internal
def _check_owner():
"""
@dev Throws if the sender is not the owner.
"""
assert msg.sender == self.owner, "ownable: caller is not the owner"
@internal
def _transfer_ownership(new_owner: address):
"""
@dev Transfers the ownership of the contract
to a new account `new_owner`.
@notice This is an `internal` function without
access restriction.
@param new_owner The 20-byte address of the new owner.
"""
old_owner: address = self.owner
self.owner = new_owner
log OwnershipTransferred(previous_owner=old_owner, new_owner=new_owner)
",
"sha256sum": "2bebfade7e8fab0293285cac09686d2747423553081e45dd9f35b25801253dc1"
},
"contracts/dao/SnapshotSplitter.vy": {
"content": "# @version 0.4.3
"""
@title Snapshot Splitter
@author Yield Basis
@license MIT
@notice Splits allocation of deposited tokens towards veCRV (old Aragon) balances who voted for specified votes
"""
from snekmate.auth import ownable
from ethereum.ercs import IERC20
initializes: ownable
exports: (
ownable.renounce_ownership,
ownable.owner
)
interface Aragon:
# VoterState: 0 = Absent, 1 = Yes, 2 = No, 3 = Even
def getVoterState(_voteID: uint256, _voter: address) -> uint8: view
def getVote(_voteID: uint256) -> VoteState: view
interface VeCRV:
def balanceOfAt(user: address, block: uint256) -> uint256: view
struct VoteState:
open: bool
executed: bool
startDate: uint64
snapshotBlock: uint256
supportRequired: uint64
minAcceptQuorum: uint64
yea: uint256
nay: uint256
votingPower: uint256
script: Bytes[1000]
struct WeightedVote:
vid: uint256
weight: uint256
block: uint256
ARAGON: public(immutable(Aragon))
VE: public(immutable(VeCRV))
TOKEN: public(immutable(IERC20))
splits: public(HashMap[uint256, HashMap[address, uint256]])
weighted_votes: public(WeightedVote[10])
address_mappings: public(HashMap[address, address])
claimed: public(HashMap[address, bool])
total_claimed: public(uint256)
@deploy
def __init__(aragon: Aragon, ve: VeCRV, token: IERC20):
"""
For Curve voting: Aragon = 0xE478de485ad2fe566d49342Cbd03E49ed7DB3356
"""
ownable.__init__()
ARAGON = aragon
VE = ve
TOKEN = token
@external
def register_split(vote_id: uint256, voter: address, yay: uint256, nay: uint256):
ownable._check_owner()
assert yay > 0 and nay > 0
self.splits[vote_id][voter] = 10**18 * yay // (yay + nay)
@external
def register_votes(vote_ids: DynArray[uint256, 10], weights: DynArray[uint256, 10], relevant_ve: DynArray[uint256, 10]):
ownable._check_owner()
total_weight: uint256 = 0
for w: uint256 in weights:
total_weight += w
i: uint256 = 0
for vid: uint256 in vote_ids:
state: VoteState = staticcall ARAGON.getVote(vid)
self.weighted_votes[i] = WeightedVote(
vid=vid,
weight=(total_weight * relevant_ve[i] // weights[i] + 1), # We will divide ve amount by this, so it has to be LARGER than the original weight
block=state.snapshotBlock
)
i += 1
@external
def register_mappings(in_addrs: DynArray[address, 20], out_addrs: DynArray[address, 20]):
ownable._check_owner()
i: uint256 = 0
for in_addr: address in in_addrs:
self.address_mappings[in_addr] = out_addrs[i]
i += 1
@internal
@view
def _get_fraction(voter: address) -> uint256:
weight: uint256 = 0
for i: uint256 in range(10):
wv: WeightedVote = self.weighted_votes[i]
if wv.block == 0:
break
vote: uint8 = staticcall ARAGON.getVoterState(wv.vid, voter)
if vote == 1:
split: uint256 = self.splits[wv.vid][voter]
if split == 0:
split = 10**18
weight += (staticcall VE.balanceOfAt(voter, wv.block)) * split // wv.weight
return weight
@external
@view
def get_fraction(voter: address) -> uint256:
return self._get_fraction(voter)
@nonreentrant
@external
def claim(_for: address = msg.sender) -> uint256:
assert ownable.owner == empty(address)
assert not self.claimed[_for], "Already claimed"
amount: uint256 = (staticcall TOKEN.balanceOf(self) + self.total_claimed) * self._get_fraction(_for) // 10**18
self.claimed[_for] = True
_to: address = self.address_mappings[_for]
if _to == empty(address):
_to = _for
self.total_claimed += amount
extcall TOKEN.transfer(_to, amount)
return amount
",
"sha256sum": "550472a6e5cc856b75a4451c68f4824096e80a9a30bb80721c912f452a79f0b6"
}
},
"settings": {
"outputSelection": {
"contracts/dao/SnapshotSplitter.vy": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
},
"search_paths": [
".venv/lib/pypy3.11/site-packages",
"."
]
},
"compiler_version": "v0.4.3+commit.bff19ea2",
"integrity": "c6b9a07d364c32cf33c29a7e55287f237a1eed7a4750e6f10074701ce34f9612"
}}
Submitted on: 2025-10-15 12:12:41
Comments
Log in to comment.
No comments yet.