Description:
Decentralized Finance (DeFi) protocol contract providing Staking functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;
contract MainnetSkyAddresses {
address internal constant SKY_ADDRESS = 0x56072C95FAA701256059aa122697B133aDEd9279;
address internal constant USDS_ADDRESS = 0xdC035D45d973E3EC169d2276DDab16f1e407384F;
address internal constant SPARK_ADDRESS = 0xc20059e0317DE91738d13af027DfC4a50781b066;
address internal constant STAKING_ENGINE = 0xCe01C90dE7FD1bcFa39e237FE6D8D9F569e8A6a3;
address internal constant LOCK_STAKE_SKY = 0xf9A9cfD3229E985B91F99Bc866d42938044FFa1C;
address internal constant USDS_FARM = 0x38E4254bD82ED5Ee97CD1C4278FAae748d998865;
address internal constant SPARK_FARM = 0x99cBC0e4E6427F6939536eD24d1275B95ff77404;
address internal constant SKY_FARM = 0xB44C2Fb4181D7Cb06bdFf34A46FdFe4a259B40Fc;
}
contract SkyHelper is MainnetSkyAddresses {
uint16 constant SKY_REFERRAL_CODE = 1002;
}
interface IJug {
struct Ilks {
uint256 duty; // borrow rate per second in 1e27
uint256 rho;
}
function ilks(bytes32) external view returns (Ilks memory);
}
interface ILockstakeEngine {
// --- Enums ---
enum FarmStatus {
UNSUPPORTED,
ACTIVE,
DELETED
}
// --- Events ---
event Open(address indexed owner, uint256 indexed index, address urn);
event SelectFarm(
address indexed owner, uint256 indexed index, address indexed farm, uint16 ref
);
event Lock(address indexed owner, uint256 indexed index, uint256 wad, uint16 ref);
event Free(
address indexed owner, uint256 indexed index, address to, uint256 wad, uint256 freed
);
event GetReward(
address indexed owner, uint256 indexed index, address indexed farm, address to, uint256 amt
);
// --- Read Functions ---
function ownerUrnsCount(address owner) external view returns (uint256);
function ownerUrns(address owner, uint256 index) external view returns (address);
function isUrnAuth(address owner, uint256 index, address usr) external view returns (bool);
function urnFarms(address urn) external view returns (address);
function vat() external view returns (address);
function ilk() external view returns (bytes32);
function jug() external view returns (address);
// --- Write Functions (Urn Management) ---
function open(uint256 index) external returns (address urn);
// --- Write Functions (Vote / Farm Selection) ---
function selectFarm(address owner, uint256 index, address farm, uint16 ref) external;
// --- Write Functions (Staking) ---
function lock(address owner, uint256 index, uint256 wad, uint16 ref) external;
function free(address owner, uint256 index, address to, uint256 wad)
external
returns (uint256 freed);
// --- Write Functions (Rewards) ---
function getReward(address owner, uint256 index, address farm, address to)
external
returns (uint256 amt);
}
interface IStakingRewards {
function stake(uint256 amount, uint16 referral) external;
function withdraw(uint256 amount) external;
function getReward() external;
function stakingToken() external view returns (address);
function rewardsToken() external view returns (address);
function balanceOf(address) external view returns (uint256);
function earned(address) external view returns (uint256);
}
interface IVat {
struct Urn {
uint256 ink; // Locked Collateral [wad]
uint256 art; // Debt [wad]
}
function urns(bytes32, address) external view returns (Urn memory);
function ilks(bytes32 ilk)
external
view
returns (uint256, uint256, uint256, uint256 line, uint256);
}
interface IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint256 digits);
function totalSupply() external view returns (uint256 supply);
function balanceOf(address _owner) external view returns (uint256 balance);
function transfer(address _to, uint256 _value) external returns (bool success);
function transferFrom(address _from, address _to, uint256 _value)
external
returns (bool success);
function approve(address _spender, uint256 _value) external returns (bool success);
function allowance(address _owner, address _spender) external view returns (uint256 remaining);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract SkyView is SkyHelper {
struct UrnInfo {
uint256 urnIndex;
address urnAddr;
address selectedFarm;
address farmRewardToken;
uint256 amountStaked;
uint256 amountBorrowed;
AmountEarnedPerFarm[] amountsEarned;
}
struct AmountEarnedPerFarm {
address farm;
address rewardToken;
uint256 amountEarned;
}
struct GeneralInfo {
uint256 totalSkyStaked; // in 1e18
uint256 debtCeiling; // in 1e45
uint256 borrowRatePerSecond; // in 1e27
uint256 totalSkyLockedInUSDSFarm;
uint256 totalSkyLockedInSparkFarm;
uint256 totalSkyLockedInSkyFarm;
}
function getUserInfo(address _user, address[] calldata _farms)
public
view
returns (UrnInfo[] memory)
{
uint256 numOfUrns = ILockstakeEngine(STAKING_ENGINE).ownerUrnsCount(_user);
UrnInfo[] memory urns = new UrnInfo[](numOfUrns);
for (uint256 i = 0; i < numOfUrns; ++i) {
urns[i] = getUrnInfo(_user, i, _farms);
}
return urns;
}
function getUrnInfo(address _user, uint256 _index, address[] calldata _farms)
public
view
returns (UrnInfo memory)
{
ILockstakeEngine engine = ILockstakeEngine(STAKING_ENGINE);
address urnAddr = engine.ownerUrns(_user, _index);
IVat.Urn memory urn = IVat(engine.vat()).urns(engine.ilk(), urnAddr);
uint256 amountStaked = urn.ink;
uint256 amountBorrowed = urn.art;
address selectedFarm = engine.urnFarms(urnAddr);
address farmRewardToken;
AmountEarnedPerFarm[] memory amountsEarned = new AmountEarnedPerFarm[](_farms.length);
if (selectedFarm != address(0)) {
farmRewardToken = IStakingRewards(selectedFarm).rewardsToken();
}
for (uint256 i = 0; i < _farms.length; ++i) {
amountsEarned[i] = AmountEarnedPerFarm({
farm: _farms[i],
rewardToken: IStakingRewards(_farms[i]).rewardsToken(),
amountEarned: IStakingRewards(_farms[i]).earned(urnAddr)
});
}
return UrnInfo({
urnIndex: _index,
urnAddr: urnAddr,
selectedFarm: selectedFarm,
farmRewardToken: farmRewardToken,
amountStaked: amountStaked,
amountBorrowed: amountBorrowed,
amountsEarned: amountsEarned
});
}
function getGeneralInfo() public view returns (GeneralInfo memory) {
uint256 totalSkyStaked = IERC20(LOCK_STAKE_SKY).totalSupply();
ILockstakeEngine engine = ILockstakeEngine(STAKING_ENGINE);
(,,, uint256 debtCeiling,) = IVat(engine.vat()).ilks(engine.ilk());
uint256 borrowRatePerSecond = IJug(engine.jug()).ilks(engine.ilk()).duty;
uint256 totalSkyLockedInUSDSFarm = IERC20(LOCK_STAKE_SKY).balanceOf(USDS_FARM);
uint256 totalSkyLockedInSparkFarm = IERC20(LOCK_STAKE_SKY).balanceOf(SPARK_FARM);
uint256 totalSkyLockedInSkyFarm = IERC20(LOCK_STAKE_SKY).balanceOf(SKY_FARM);
return GeneralInfo({
totalSkyStaked: totalSkyStaked,
debtCeiling: debtCeiling,
borrowRatePerSecond: borrowRatePerSecond,
totalSkyLockedInUSDSFarm: totalSkyLockedInUSDSFarm,
totalSkyLockedInSparkFarm: totalSkyLockedInSparkFarm,
totalSkyLockedInSkyFarm: totalSkyLockedInSkyFarm
});
}
}
Submitted on: 2025-11-04 16:41:46
Comments
Log in to comment.
No comments yet.