Skip to content

Commit 79fbcc4

Browse files
committed
feat: exchange contract with yield tracking
1 parent fa21bc6 commit 79fbcc4

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

src/Exchange.sol

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ contract Exchange is ReentrancyGuard, Ownable {
2424
uint256 public fee = 100; // 100 basis points fee (1%)
2525
address public feeCollector;
2626

27+
uint256 public lastUpdateTime;
28+
uint256 public lastPricePerShare;
29+
2730
event Transfer(address indexed from, address indexed to, uint256 amount, string uen);
2831
event FeeUpdated(uint256 newFee);
2932
event FeeCollectorUpdated(address newFeeCollector);
@@ -39,6 +42,8 @@ contract Exchange is ReentrancyGuard, Ownable {
3942
usdcToken = IERC20(_usdcAddress);
4043
feeCollector = address(this);
4144
vault = IERC4626(_vaultAddress);
45+
lastUpdateTime = block.timestamp;
46+
lastPricePerShare = vault.convertToAssets(1e6);
4247
}
4348

4449
/////////////////////////
@@ -161,4 +166,89 @@ contract Exchange is ReentrancyGuard, Ownable {
161166
usdcToken.safeTransfer(_to, _amount);
162167
emit FeesWithdrawn(_to, _amount);
163168
}
169+
170+
/**
171+
* @notice Get current price per share
172+
* @return Current price of 1 share in terms of assets (USDC)
173+
*/
174+
function getCurrentPricePerShare() public view returns (uint256) {
175+
return vault.convertToAssets(1e6);
176+
}
177+
178+
/**
179+
* @notice Get vault metrics
180+
* @return totalAssets Total assets in vault
181+
* @return totalShares Total shares issued
182+
* @return pricePerShare Current price per share
183+
*/
184+
function getVaultMetrics() public view returns (uint256 totalAssets, uint256 totalShares, uint256 pricePerShare) {
185+
totalAssets = vault.totalAssets();
186+
totalShares = vault.totalSupply();
187+
pricePerShare = getCurrentPricePerShare();
188+
}
189+
190+
/**
191+
* @notice Calculate APY between two price points
192+
* @param startPrice Starting price per share
193+
* @param endPrice Ending price per share
194+
* @param timeElapsedInSeconds Time elapsed between prices in seconds
195+
* @return apy Annual Percentage Yield in basis points (1% = 100)
196+
*/
197+
function calculateAPY(uint256 startPrice, uint256 endPrice, uint256 timeElapsedInSeconds)
198+
public
199+
pure
200+
returns (uint256 apy)
201+
{
202+
require(timeElapsedInSeconds > 0, "Time elapsed must be > 0");
203+
require(startPrice > 0, "Start price must be > 0");
204+
205+
// Calculate yield for the period
206+
uint256 yield = ((endPrice - startPrice) * 1e6) / startPrice;
207+
208+
// Annualize it (multiply by seconds in year and divide by elapsed time)
209+
uint256 secondsInYear = 365 days;
210+
apy = (yield * secondsInYear) / timeElapsedInSeconds;
211+
212+
return apy;
213+
}
214+
215+
/**
216+
* @notice Get current APY based on last update
217+
* @return Current APY in basis points (1% = 100)
218+
*/
219+
function getCurrentAPY() external view returns (uint256) {
220+
uint256 currentPrice = getCurrentPricePerShare();
221+
uint256 timeElapsed = block.timestamp - lastUpdateTime;
222+
223+
return calculateAPY(lastPricePerShare, currentPrice, timeElapsed);
224+
}
225+
226+
/**
227+
* @notice Update the stored price per share
228+
* @dev This can be called periodically to update the reference point for APY calculations
229+
*/
230+
function updatePricePerShare() external {
231+
lastPricePerShare = getCurrentPricePerShare();
232+
lastUpdateTime = block.timestamp;
233+
}
234+
235+
/**
236+
* @notice Get detailed yield information
237+
* @return currentPrice Current price per share
238+
* @return lastPrice Last recorded price per share
239+
* @return timeSinceLastUpdate Seconds since last update
240+
* @return currentAPY Current APY in basis points
241+
*/
242+
function getYieldInfo()
243+
external
244+
view
245+
returns (uint256 currentPrice, uint256 lastPrice, uint256 timeSinceLastUpdate, uint256 currentAPY)
246+
{
247+
currentPrice = getCurrentPricePerShare();
248+
lastPrice = lastPricePerShare;
249+
timeSinceLastUpdate = block.timestamp - lastUpdateTime;
250+
currentAPY = calculateAPY(lastPrice, currentPrice, timeSinceLastUpdate);
251+
252+
return (currentPrice, lastPrice, timeSinceLastUpdate, currentAPY);
253+
}
164254
}

0 commit comments

Comments
 (0)