pragmasolidity 0.5.17;import"./KASSIAHOMEGovernance.sol";
contractKASSIAHOMETokenisKASSIAHOMEGovernanceToken{
// ModifiersmodifieronlyGov() {
require(msg.sender== gov);
_;
}
modifieronlyRebaser() {
require(msg.sender== rebaser);
_;
}
modifieronlyMinter() {
require(msg.sender== rebaser ||msg.sender== incentivizer ||msg.sender== gov, "not minter");
_;
}
modifiervalidRecipient(address to) {
require(to !=address(0x0));
require(to !=address(this));
_;
}
functioninitialize(stringmemory name_,
stringmemory symbol_,
uint8 decimals_
)
public{
require(kassiahomesScalingFactor ==0, "already initialized");
name = name_;
symbol = symbol_;
decimals = decimals_;
}
/**
* @notice Computes the current max scaling factor
*/functionmaxScalingFactor()
externalviewreturns (uint256)
{
return _maxScalingFactor();
}
function_maxScalingFactor()
internalviewreturns (uint256)
{
// scaling factor can only go up to 2**256-1 = initSupply * kassiahomesScalingFactor// this is used to check if kassiahomesScalingFactor will be too high to compute balances when rebasing.returnuint256(-1) / initSupply;
}
/**
* @notice Mints new tokens, increasing totalSupply, initSupply, and a users balance.
* @dev Limited to onlyMinter modifier
*/functionmint(address to, uint256 amount)
externalonlyMinterreturns (bool)
{
_mint(to, amount);
returntrue;
}
function_mint(address to, uint256 amount)
internal{
// increase totalSupply
totalSupply = totalSupply.add(amount);
// get underlying valueuint256 kassiahomeValue = amount.mul(internalDecimals).div(kassiahomesScalingFactor);
// increase initSupply
initSupply = initSupply.add(kassiahomeValue);
// make sure the mint didnt push maxScalingFactor too lowrequire(kassiahomesScalingFactor <= _maxScalingFactor(), "max scaling factor too low");
// add balance
_kassiahomeBalances[to] = _kassiahomeBalances[to].add(kassiahomeValue);
// add delegates to the minter
_moveDelegates(address(0), _delegates[to], kassiahomeValue);
emit Mint(to, amount);
}
/* - ERC20 functionality - *//**
* @dev Transfer tokens to a specified address.
* @param to The address to transfer to.
* @param value The amount to be transferred.
* @return True on success, false otherwise.
*/functiontransfer(address to, uint256 value)
externalvalidRecipient(to)
returns (bool)
{
// underlying balance is stored in kassiahomes, so divide by current scaling factor// note, this means as scaling factor grows, dust will be untransferrable.// minimum transfer value == kassiahomesScalingFactor / 1e24;// get amount in underlyinguint256 kassiahomeValue = value.mul(internalDecimals).div(kassiahomesScalingFactor);
// sub from balance of sender
_kassiahomeBalances[msg.sender] = _kassiahomeBalances[msg.sender].sub(kassiahomeValue);
// add to balance of receiver
_kassiahomeBalances[to] = _kassiahomeBalances[to].add(kassiahomeValue);
emit Transfer(msg.sender, to, value);
_moveDelegates(_delegates[msg.sender], _delegates[to], kassiahomeValue);
returntrue;
}
/**
* @dev Transfer tokens from one address to another.
* @param from The address you want to send tokens from.
* @param to The address you want to transfer to.
* @param value The amount of tokens to be transferred.
*/functiontransferFrom(addressfrom, address to, uint256 value)
externalvalidRecipient(to)
returns (bool)
{
// decrease allowance
_allowedFragments[from][msg.sender] = _allowedFragments[from][msg.sender].sub(value);
// get value in kassiahomesuint256 kassiahomeValue = value.mul(internalDecimals).div(kassiahomesScalingFactor);
// sub from from
_kassiahomeBalances[from] = _kassiahomeBalances[from].sub(kassiahomeValue);
_kassiahomeBalances[to] = _kassiahomeBalances[to].add(kassiahomeValue);
emit Transfer(from, to, value);
_moveDelegates(_delegates[from], _delegates[to], kassiahomeValue);
returntrue;
}
/**
* @param who The address to query.
* @return The balance of the specified address.
*/functionbalanceOf(address who)
externalviewreturns (uint256)
{
return _kassiahomeBalances[who].mul(kassiahomesScalingFactor).div(internalDecimals);
}
/** @notice Currently returns the internal storage amount
* @param who The address to query.
* @return The underlying balance of the specified address.
*/functionbalanceOfUnderlying(address who)
externalviewreturns (uint256)
{
return _kassiahomeBalances[who];
}
/**
* @dev Function to check the amount of tokens that an owner has allowed to a spender.
* @param owner_ The address which owns the funds.
* @param spender The address which will spend the funds.
* @return The number of tokens still available for the spender.
*/functionallowance(address owner_, address spender)
externalviewreturns (uint256)
{
return _allowedFragments[owner_][spender];
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of
* msg.sender. This method is included for ERC20 compatibility.
* increaseAllowance and decreaseAllowance should be used instead.
* Changing an allowance with this method brings the risk that someone may transfer both
* the old and the new allowance - if they are both greater than zero - if a transfer
* transaction is mined before the later approve() call is mined.
*
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/functionapprove(address spender, uint256 value)
externalreturns (bool)
{
_allowedFragments[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
returntrue;
}
/**
* @dev Increase the amount of tokens that an owner has allowed to a spender.
* This method should be used instead of approve() to avoid the double approval vulnerability
* described above.
* @param spender The address which will spend the funds.
* @param addedValue The amount of tokens to increase the allowance by.
*/functionincreaseAllowance(address spender, uint256 addedValue)
externalreturns (bool)
{
_allowedFragments[msg.sender][spender] =
_allowedFragments[msg.sender][spender].add(addedValue);
emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]);
returntrue;
}
/**
* @dev Decrease the amount of tokens that an owner has allowed to a spender.
*
* @param spender The address which will spend the funds.
* @param subtractedValue The amount of tokens to decrease the allowance by.
*/functiondecreaseAllowance(address spender, uint256 subtractedValue)
externalreturns (bool)
{
uint256 oldValue = _allowedFragments[msg.sender][spender];
if (subtractedValue >= oldValue) {
_allowedFragments[msg.sender][spender] =0;
} else {
_allowedFragments[msg.sender][spender] = oldValue.sub(subtractedValue);
}
emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]);
returntrue;
}
/* - Governance Functions - *//** @notice sets the rebaser
* @param rebaser_ The address of the rebaser contract to use for authentication.
*/function_setRebaser(address rebaser_)
externalonlyGov{
address oldRebaser = rebaser;
rebaser = rebaser_;
emit NewRebaser(oldRebaser, rebaser_);
}
/** @notice sets the incentivizer
* @param incentivizer_ The address of the rebaser contract to use for authentication.
*/function_setIncentivizer(address incentivizer_)
externalonlyGov{
address oldIncentivizer = incentivizer;
incentivizer = incentivizer_;
emit NewIncentivizer(oldIncentivizer, incentivizer_);
}
/** @notice sets the pendingGov
* @param pendingGov_ The address of the rebaser contract to use for authentication.
*/function_setPendingGov(address pendingGov_)
externalonlyGov{
address oldPendingGov = pendingGov;
pendingGov = pendingGov_;
emit NewPendingGov(oldPendingGov, pendingGov_);
}
/** @notice lets msg.sender accept governance
*
*/function_acceptGov()
external{
require(msg.sender== pendingGov, "!pending");
address oldGov = gov;
gov = pendingGov;
pendingGov =address(0);
emit NewGov(oldGov, gov);
}
/* - Extras - *//**
* @notice Initiates a new rebase operation, provided the minimum time period has elapsed.
*
* @dev The supply adjustment equals (totalSupply * DeviationFromTargetRate) / rebaseLag
* Where DeviationFromTargetRate is (MarketOracleRate - targetRate) / targetRate
* and targetRate is CpiOracleRate / baseCpi
*/functionrebase(uint256 epoch,
uint256 indexDelta,
bool positive
)
externalonlyRebaserreturns (uint256)
{
if (indexDelta ==0) {
emit Rebase(epoch, kassiahomesScalingFactor, kassiahomesScalingFactor);
return totalSupply;
}
uint256 prevKassiahomesScalingFactor = kassiahomesScalingFactor;
if (!positive) {
kassiahomesScalingFactor = kassiahomesScalingFactor.mul(BASE.sub(indexDelta)).div(BASE);
} else {
uint256 newScalingFactor = kassiahomesScalingFactor.mul(BASE.add(indexDelta)).div(BASE);
if (newScalingFactor < _maxScalingFactor()) {
kassiahomesScalingFactor = newScalingFactor;
} else {
kassiahomesScalingFactor = _maxScalingFactor();
}
}
totalSupply = initSupply.mul(kassiahomesScalingFactor);
emit Rebase(epoch, prevKassiahomesScalingFactor, kassiahomesScalingFactor);
return totalSupply;
}
}
contractKASSIAHOMEisKASSIAHOMEToken{
/**
* @notice Initialize the new money market
* @param name_ ERC-20 name of this token
* @param symbol_ ERC-20 symbol of this token
* @param decimals_ ERC-20 decimal precision of this token
*/functioninitialize(stringmemory name_,
stringmemory symbol_,
uint8 decimals_,
address initial_owner,
uint256 initSupply_
)
public{
require(initSupply_ >0, "0 init supply");
super.initialize(name_, symbol_, decimals_);
initSupply = initSupply_.mul(10**24/ (BASE));
totalSupply = initSupply_;
kassiahomesScalingFactor = BASE;
_kassiahomeBalances[initial_owner] = initSupply_.mul(10**24/ (BASE));
// owner renounces ownership after deployment as they need to set// rebaser and incentivizer// gov = gov_;
}
}
Contract Source Code
File 2 of 8: KASSIAHOMEDelegate.sol
pragmasolidity 0.5.17;import"./KASSIAHOME.sol";
contractKASSIAHOMEDelegationStorage{
/**
* @notice Implementation address for this contract
*/addresspublic implementation;
}
contractKASSIAHOMEDelegatorInterfaceisKASSIAHOMEDelegationStorage{
/**
* @notice Emitted when implementation is changed
*/eventNewImplementation(address oldImplementation, address newImplementation);
/**
* @notice Called by the gov to update the implementation of the delegator
* @param implementation_ The address of the new implementation for delegation
* @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation
* @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation
*/function_setImplementation(address implementation_, bool allowResign, bytesmemory becomeImplementationData) public;
}
contractKASSIAHOMEDelegateInterfaceisKASSIAHOMEDelegationStorage{
/**
* @notice Called by the delegator on a delegate to initialize it for duty
* @dev Should revert if any issues arise which make it unfit for delegation
* @param data The encoded bytes data for any initialization
*/function_becomeImplementation(bytesmemory data) public;
/**
* @notice Called by the delegator on a delegate to forfeit its responsibility
*/function_resignImplementation() public;
}
contractKASSIAHOMEDelegateisKASSIAHOME, KASSIAHOMEDelegateInterface{
/**
* @notice Construct an empty delegate
*/constructor() public{}
/**
* @notice Called by the delegator on a delegate to initialize it for duty
* @param data The encoded bytes data for any initialization
*/function_becomeImplementation(bytesmemory data) public{
// Shh -- currently unused
data;
// Shh -- we don't ever want this hook to be marked pureif (false) {
implementation =address(0);
}
require(msg.sender== gov, "only the gov may call _becomeImplementation");
}
/**
* @notice Called by the delegator on a delegate to forfeit its responsibility
*/function_resignImplementation() public{
// Shh -- we don't ever want this hook to be marked pureif (false) {
implementation =address(0);
}
require(msg.sender== gov, "only the gov may call _resignImplementation");
}
}
Contract Source Code
File 3 of 8: KASSIAHOMEDelegator.sol
pragmasolidity 0.5.17;import"./KASSIAHOMETokenInterface.sol";
import"./KASSIAHOMEDelegate.sol";
contractKASSIAHOMEDelegatorisKASSIAHOMETokenInterface, KASSIAHOMEDelegatorInterface{
/**
* @notice Construct a new KASSIAHOME
* @param name_ ERC-20 name of this token
* @param symbol_ ERC-20 symbol of this token
* @param decimals_ ERC-20 decimal precision of this token
* @param initSupply_ Initial token amount
* @param implementation_ The address of the implementation the contract delegates to
* @param becomeImplementationData The encoded args for becomeImplementation
*/constructor(stringmemory name_,
stringmemory symbol_,
uint8 decimals_,
uint256 initSupply_,
address implementation_,
bytesmemory becomeImplementationData
)
public{
// Creator of the contract is gov during initialization
gov =msg.sender;
// First delegate gets to initialize the delegator (i.e. storage contract)
delegateTo(
implementation_,
abi.encodeWithSignature(
"initialize(string,string,uint8,address,uint256)",
name_,
symbol_,
decimals_,
msg.sender,
initSupply_
)
);
// New implementations always get set via the settor (post-initialize)
_setImplementation(implementation_, false, becomeImplementationData);
}
/**
* @notice Called by the gov to update the implementation of the delegator
* @param implementation_ The address of the new implementation for delegation
* @param allowResign Flag to indicate whether to call _resignImplementation on the old implementation
* @param becomeImplementationData The encoded bytes data to be passed to _becomeImplementation
*/function_setImplementation(address implementation_, bool allowResign, bytesmemory becomeImplementationData) public{
require(msg.sender== gov, "KASSIAHOMEDelegator::_setImplementation: Caller must be gov");
if (allowResign) {
delegateToImplementation(abi.encodeWithSignature("_resignImplementation()"));
}
address oldImplementation = implementation;
implementation = implementation_;
delegateToImplementation(abi.encodeWithSignature("_becomeImplementation(bytes)", becomeImplementationData));
emit NewImplementation(oldImplementation, implementation);
}
/**
* @notice Sender supplies assets into the market and receives cTokens in exchange
* @dev Accrues interest whether or not the operation succeeds, unless reverted
* @param mintAmount The amount of the underlying asset to supply
* @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
*/functionmint(address to, uint256 mintAmount)
externalreturns (bool)
{
to; mintAmount; // Shh
delegateAndReturn();
}
/**
* @notice Transfer `amount` tokens from `msg.sender` to `dst`
* @param dst The address of the destination account
* @param amount The number of tokens to transfer
* @return Whether or not the transfer succeeded
*/functiontransfer(address dst, uint256 amount)
externalreturns (bool)
{
dst; amount; // Shh
delegateAndReturn();
}
/**
* @notice Transfer `amount` tokens from `src` to `dst`
* @param src The address of the source account
* @param dst The address of the destination account
* @param amount The number of tokens to transfer
* @return Whether or not the transfer succeeded
*/functiontransferFrom(address src,
address dst,
uint256 amount
)
externalreturns (bool)
{
src; dst; amount; // Shh
delegateAndReturn();
}
/**
* @notice Approve `spender` to transfer up to `amount` from `src`
* @dev This will overwrite the approval amount for `spender`
* and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
* @param spender The address of the account which may transfer tokens
* @param amount The number of tokens that are approved (-1 means infinite)
* @return Whether or not the approval succeeded
*/functionapprove(address spender,
uint256 amount
)
externalreturns (bool)
{
spender; amount; // Shh
delegateAndReturn();
}
/**
* @dev Increase the amount of tokens that an owner has allowed to a spender.
* This method should be used instead of approve() to avoid the double approval vulnerability
* described above.
* @param spender The address which will spend the funds.
* @param addedValue The amount of tokens to increase the allowance by.
*/functionincreaseAllowance(address spender,
uint256 addedValue
)
externalreturns (bool)
{
spender; addedValue; // Shh
delegateAndReturn();
}
functionmaxScalingFactor()
externalviewreturns (uint256)
{
delegateToViewAndReturn();
}
functionrebase(uint256 epoch,
uint256 indexDelta,
bool positive
)
externalreturns (uint256)
{
epoch; indexDelta; positive;
delegateAndReturn();
}
/**
* @dev Decrease the amount of tokens that an owner has allowed to a spender.
*
* @param spender The address which will spend the funds.
* @param subtractedValue The amount of tokens to decrease the allowance by.
*/functiondecreaseAllowance(address spender,
uint256 subtractedValue
)
externalreturns (bool)
{
spender; subtractedValue; // Shh
delegateAndReturn();
}
/**
* @notice Get the current allowance from `owner` for `spender`
* @param owner The address of the account which owns the tokens to be spent
* @param spender The address of the account which may transfer tokens
* @return The number of tokens allowed to be spent (-1 means infinite)
*/functionallowance(address owner,
address spender
)
externalviewreturns (uint256)
{
owner; spender; // Shh
delegateToViewAndReturn();
}
/**
* @notice Get the current allowance from `owner` for `spender`
* @param delegator The address of the account which has designated a delegate
* @return Address of delegatee
*/functiondelegates(address delegator
)
externalviewreturns (address)
{
delegator; // Shh
delegateToViewAndReturn();
}
/**
* @notice Get the token balance of the `owner`
* @param owner The address of the account to query
* @return The number of tokens owned by `owner`
*/functionbalanceOf(address owner)
externalviewreturns (uint256)
{
owner; // Shh
delegateToViewAndReturn();
}
/**
* @notice Currently unused. For future compatability
* @param owner The address of the account to query
* @return The number of underlying tokens owned by `owner`
*/functionbalanceOfUnderlying(address owner)
externalviewreturns (uint256)
{
owner; // Shh
delegateToViewAndReturn();
}
/*** Gov Functions ***//**
* @notice Begins transfer of gov rights. The newPendingGov must call `_acceptGov` to finalize the transfer.
* @dev Gov function to begin change of gov. The newPendingGov must call `_acceptGov` to finalize the transfer.
* @param newPendingGov New pending gov.
*/function_setPendingGov(address newPendingGov)
external{
newPendingGov; // Shh
delegateAndReturn();
}
function_setRebaser(address rebaser_)
external{
rebaser_; // Shh
delegateAndReturn();
}
function_setIncentivizer(address incentivizer_)
external{
incentivizer_; // Shh
delegateAndReturn();
}
/**
* @notice Accepts transfer of gov rights. msg.sender must be pendingGov
* @dev Gov function for pending gov to accept role and update gov
* @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
*/function_acceptGov()
external{
delegateAndReturn();
}
functiongetPriorVotes(address account, uint blockNumber)
externalviewreturns (uint256)
{
account; blockNumber;
delegateToViewAndReturn();
}
functiondelegateBySig(address delegatee,
uint nonce,
uint expiry,
uint8 v,
bytes32 r,
bytes32 s
)
external{
delegatee; nonce; expiry; v; r; s;
delegateAndReturn();
}
functiondelegate(address delegatee)
external{
delegatee;
delegateAndReturn();
}
functiongetCurrentVotes(address account)
externalviewreturns (uint256)
{
account;
delegateToViewAndReturn();
}
/**
* @notice Internal method to delegate execution to another contract
* @dev It returns to the external caller whatever the implementation returns or forwards reverts
* @param callee The contract to delegatecall
* @param data The raw data to delegatecall
* @return The returned bytes from the delegatecall
*/functiondelegateTo(address callee, bytesmemory data) internalreturns (bytesmemory) {
(bool success, bytesmemory returnData) = callee.delegatecall(data);
assembly {
ifeq(success, 0) {
revert(add(returnData, 0x20), returndatasize)
}
}
return returnData;
}
/**
* @notice Delegates execution to the implementation contract
* @dev It returns to the external caller whatever the implementation returns or forwards reverts
* @param data The raw data to delegatecall
* @return The returned bytes from the delegatecall
*/functiondelegateToImplementation(bytesmemory data) publicreturns (bytesmemory) {
return delegateTo(implementation, data);
}
/**
* @notice Delegates execution to an implementation contract
* @dev It returns to the external caller whatever the implementation returns or forwards reverts
* There are an additional 2 prefix uints from the wrapper returndata, which we ignore since we make an extra hop.
* @param data The raw data to delegatecall
* @return The returned bytes from the delegatecall
*/functiondelegateToViewImplementation(bytesmemory data) publicviewreturns (bytesmemory) {
(bool success, bytesmemory returnData) =address(this).staticcall(abi.encodeWithSignature("delegateToImplementation(bytes)", data));
assembly {
ifeq(success, 0) {
revert(add(returnData, 0x20), returndatasize)
}
}
returnabi.decode(returnData, (bytes));
}
functiondelegateToViewAndReturn() privateviewreturns (bytesmemory) {
(bool success, ) =address(this).staticcall(abi.encodeWithSignature("delegateToImplementation(bytes)", msg.data));
assembly {
let free_mem_ptr :=mload(0x40)
returndatacopy(free_mem_ptr, 0, returndatasize)
switch success
case0 { revert(free_mem_ptr, returndatasize) }
default { return(add(free_mem_ptr, 0x40), returndatasize) }
}
}
functiondelegateAndReturn() privatereturns (bytesmemory) {
(bool success, ) = implementation.delegatecall(msg.data);
assembly {
let free_mem_ptr :=mload(0x40)
returndatacopy(free_mem_ptr, 0, returndatasize)
switch success
case0 { revert(free_mem_ptr, returndatasize) }
default { return(free_mem_ptr, returndatasize) }
}
}
/**
* @notice Delegates execution to an implementation contract
* @dev It returns to the external caller whatever the implementation returns or forwards reverts
*/function () externalpayable{
require(msg.value==0,"KASSIAHOMEDelegator:fallback: cannot send value to fallback");
// delegate all other functions to current implementation
delegateAndReturn();
}
}
Contract Source Code
File 4 of 8: KASSIAHOMEGovernance.sol
pragmasolidity 0.5.17;pragmaexperimentalABIEncoderV2;import"./KASSIAHOMEGovernanceStorage.sol";
import"./KASSIAHOMETokenInterface.sol";
contractKASSIAHOMEGovernanceTokenisKASSIAHOMETokenInterface{
/// @notice An event thats emitted when an account changes its delegateeventDelegateChanged(addressindexed delegator, addressindexed fromDelegate, addressindexed toDelegate);
/// @notice An event thats emitted when a delegate account's vote balance changeseventDelegateVotesChanged(addressindexed delegate, uint previousBalance, uint newBalance);
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegator The address to get delegatee for
*/functiondelegates(address delegator)
externalviewreturns (address)
{
return _delegates[delegator];
}
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegatee The address to delegate votes to
*/functiondelegate(address delegatee) external{
return _delegate(msg.sender, delegatee);
}
/**
* @notice Delegates votes from signatory to `delegatee`
* @param delegatee The address to delegate votes to
* @param nonce The contract state required to match the signature
* @param expiry The time at which to expire the signature
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/functiondelegateBySig(address delegatee,
uint nonce,
uint expiry,
uint8 v,
bytes32 r,
bytes32 s
)
external{
bytes32 domainSeparator =keccak256(
abi.encode(
DOMAIN_TYPEHASH,
keccak256(bytes(name)),
getChainId(),
address(this)
)
);
bytes32 structHash =keccak256(
abi.encode(
DELEGATION_TYPEHASH,
delegatee,
nonce,
expiry
)
);
bytes32 digest =keccak256(
abi.encodePacked(
"\x19\x01",
domainSeparator,
structHash
)
);
address signatory =ecrecover(digest, v, r, s);
require(signatory !=address(0), "KASSIAHOME::delegateBySig: invalid signature");
require(nonce == nonces[signatory]++, "KASSIAHOME::delegateBySig: invalid nonce");
require(now<= expiry, "KASSIAHOME::delegateBySig: signature expired");
return _delegate(signatory, delegatee);
}
/**
* @notice Gets the current votes balance for `account`
* @param account The address to get votes balance
* @return The number of current votes for `account`
*/functiongetCurrentVotes(address account)
externalviewreturns (uint256)
{
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints >0 ? checkpoints[account][nCheckpoints -1].votes : 0;
}
/**
* @notice Determine the prior number of votes for an account as of a block number
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
* @param account The address of the account to check
* @param blockNumber The block number to get the vote balance at
* @return The number of votes the account had as of the given block
*/functiongetPriorVotes(address account, uint blockNumber)
externalviewreturns (uint256)
{
require(blockNumber <block.number, "KASSIAHOME::getPriorVotes: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints ==0) {
return0;
}
// First check most recent balanceif (checkpoints[account][nCheckpoints -1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints -1].votes;
}
// Next check implicit zero balanceif (checkpoints[account][0].fromBlock > blockNumber) {
return0;
}
uint32 lower =0;
uint32 upper = nCheckpoints -1;
while (upper > lower) {
uint32 center = upper - (upper - lower) /2; // ceil, avoiding overflow
Checkpoint memory cp = checkpoints[account][center];
if (cp.fromBlock == blockNumber) {
return cp.votes;
} elseif (cp.fromBlock < blockNumber) {
lower = center;
} else {
upper = center -1;
}
}
return checkpoints[account][lower].votes;
}
function_delegate(address delegator, address delegatee)
internal{
address currentDelegate = _delegates[delegator];
uint256 delegatorBalance = _kassiahomeBalances[delegator]; // balance of underlying KASSIAHOMEs (not scaled);
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
function_moveDelegates(address srcRep, address dstRep, uint256 amount) internal{
if (srcRep != dstRep && amount >0) {
if (srcRep !=address(0)) {
// decrease old representativeuint32 srcRepNum = numCheckpoints[srcRep];
uint256 srcRepOld = srcRepNum >0 ? checkpoints[srcRep][srcRepNum -1].votes : 0;
uint256 srcRepNew = srcRepOld.sub(amount);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep !=address(0)) {
// increase new representativeuint32 dstRepNum = numCheckpoints[dstRep];
uint256 dstRepOld = dstRepNum >0 ? checkpoints[dstRep][dstRepNum -1].votes : 0;
uint256 dstRepNew = dstRepOld.add(amount);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
function_writeCheckpoint(address delegatee,
uint32 nCheckpoints,
uint256 oldVotes,
uint256 newVotes
)
internal{
uint32 blockNumber = safe32(block.number, "KASSIAHOME::_writeCheckpoint: block number exceeds 32 bits");
if (nCheckpoints >0&& checkpoints[delegatee][nCheckpoints -1].fromBlock == blockNumber) {
checkpoints[delegatee][nCheckpoints -1].votes = newVotes;
} else {
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
numCheckpoints[delegatee] = nCheckpoints +1;
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
functionsafe32(uint n, stringmemory errorMessage) internalpurereturns (uint32) {
require(n <2**32, errorMessage);
returnuint32(n);
}
functiongetChainId() internalpurereturns (uint) {
uint256 chainId;
assembly { chainId :=chainid() }
return chainId;
}
}
Contract Source Code
File 5 of 8: KASSIAHOMEGovernanceStorage.sol
pragmasolidity 0.5.17;pragmaexperimentalABIEncoderV2;contractKASSIAHOMEGovernanceStorage{
/// @notice A record of each accounts delegatemapping (address=>address) internal _delegates;
/// @notice A checkpoint for marking number of votes from a given blockstructCheckpoint {
uint32 fromBlock;
uint256 votes;
}
/// @notice A record of votes checkpoints for each account, by indexmapping (address=>mapping (uint32=> Checkpoint)) public checkpoints;
/// @notice The number of checkpoints for each accountmapping (address=>uint32) public numCheckpoints;
/// @notice The EIP-712 typehash for the contract's domainbytes32publicconstant DOMAIN_TYPEHASH =keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
/// @notice The EIP-712 typehash for the delegation struct used by the contractbytes32publicconstant DELEGATION_TYPEHASH =keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
/// @notice A record of states for signing / validating signaturesmapping (address=>uint) public nonces;
}
pragmasolidity 0.5.17;import"./SafeMath.sol";
// Storage for a KASSIAHOME tokencontractKASSIAHOMETokenStorage{
usingSafeMathforuint256;
/**
* @dev Guard variable for re-entrancy checks. Not currently used
*/boolinternal _notEntered;
/**
* @notice EIP-20 token name for this token
*/stringpublic name;
/**
* @notice EIP-20 token symbol for this token
*/stringpublic symbol;
/**
* @notice EIP-20 token decimals for this token
*/uint8public decimals;
/**
* @notice Governor for this contract
*/addresspublic gov;
/**
* @notice Pending governance for this contract
*/addresspublic pendingGov;
/**
* @notice Approved rebaser for this contract
*/addresspublic rebaser;
/**
* @notice Reserve address of KASSIAHOME protocol
*/addresspublic incentivizer;
/**
* @notice Total supply of KASSIAHOMEs
*/uint256public totalSupply;
/**
* @notice Internal decimals used to handle scaling factor
*/uint256publicconstant internalDecimals =10**24;
/**
* @notice Used for percentage maths
*/uint256publicconstant BASE =10**18;
/**
* @notice Scaling factor that adjusts everyone's balances
*/uint256public kassiahomesScalingFactor;
mapping (address=>uint256) internal _kassiahomeBalances;
mapping (address=>mapping (address=>uint256)) internal _allowedFragments;
uint256public initSupply;
}
Contract Source Code
File 8 of 8: SafeMath.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.5.17;/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522if (a ==0) {
return0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b !=0, errorMessage);
return a % b;
}
}