package fundmarket import ( "math/big" "net/http" "strings" "github.com/gin-gonic/gin" db "github.com/gothinkster/golang-gin-realworld-example-app/common" ) // GetNetDeposited computes the net USDC deposited by a wallet address across all YT vaults. // // GET /api/fundmarket/net-deposited?address=0x...&chain_id=97 // // Net deposited = Σ(amountIn WHERE tokenIn=USDC) - Σ(amountOut WHERE tokenOut=USDC) // (buy YT: USDC → YT, tokenIn=USDC; sell YT: YT → USDC, tokenOut=USDC) // // Returns netDepositedUSD (float64) for the frontend to compute: // Your Total Earning = currentValue (on-chain) - netDepositedUSD func GetNetDeposited(c *gin.Context) { address := strings.ToLower(c.Query("address")) if address == "" { c.JSON(http.StatusBadRequest, gin.H{"success": false, "error": "address required"}) return } chainIDStr := c.DefaultQuery("chain_id", "97") database := db.GetDB() // Look up USDC address for this chain (token_role = 'stablecoin') var usdcAddr struct { ContractAddress string `gorm:"column:contract_address"` } if err := database.Table("assets"). Where("token_role = 'stablecoin' AND chain_id = ?", chainIDStr). Select("contract_address"). First(&usdcAddr).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "USDC address not found"}) return } usdcAddress := strings.ToLower(usdcAddr.ContractAddress) // Sum amountIn where tokenIn = USDC (user bought YT, paid USDC) type sumResult struct { Total string } var buySum sumResult database.Raw(` SELECT COALESCE(SUM(CAST(amount_in AS DECIMAL(65,0))), 0) AS total FROM yt_swap_records WHERE account = ? AND chain_id = ? AND LOWER(token_in) = ? `, address, chainIDStr, usdcAddress).Scan(&buySum) // Sum amountOut where tokenOut = USDC (user sold YT, received USDC) var sellSum sumResult database.Raw(` SELECT COALESCE(SUM(CAST(amount_out AS DECIMAL(65,0))), 0) AS total FROM yt_swap_records WHERE account = ? AND chain_id = ? AND LOWER(token_out) = ? `, address, chainIDStr, usdcAddress).Scan(&sellSum) buyWei, _ := new(big.Int).SetString(buySum.Total, 10) sellWei, _ := new(big.Int).SetString(sellSum.Total, 10) if buyWei == nil { buyWei = big.NewInt(0) } if sellWei == nil { sellWei = big.NewInt(0) } netWei := new(big.Int).Sub(buyWei, sellWei) if netWei.Sign() < 0 { netWei = big.NewInt(0) } // Convert from 18-decimal wei to float64 USD divisor := new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) netUSD, _ := new(big.Float).Quo(new(big.Float).SetInt(netWei), divisor).Float64() c.JSON(http.StatusOK, gin.H{ "success": true, "data": gin.H{ "address": address, "chainId": chainIDStr, "usdcAddress": usdcAddress, "buyWei": buyWei.String(), "sellWei": sellWei.String(), "netDepositedWei": netWei.String(), "netDepositedUSD": netUSD, }, }) }