/// @notice Withdraws tokens in proportion to the vault's holdings.
 /// @param shares Shares burned by sender
 /// @param amount0Min Revert if resulting `amount0` is smaller than this
 /// @param amount1Min Revert if resulting `amount1` is smaller than this
 /// @param to Recipient of tokens
 /// @return amount0 Amount of token0 sent to recipient
 /// @return amount1 Amount of token1 sent to recipient
 function withdraw(
 uint256 shares,
 uint256 amount0Min,
 uint256 amount1Min,
 address to
 ) external virtual returns (uint256 amount0, uint256 amount1) {
 // Shares to withdraw must be greater than zero
 require(shares > 0);

 uint256 \_totalSupply = totalSupply();

 // Burn LPTs
 \_burn(msg.sender, shares);

 // Calculate token amounts proportional to unused balances
 // LP value = (Value deposited in Uniswap + value held in vault undeposited) / total LP tokens.
 // Here we calculate value held in vault undeposited.
 // No div(0) safemath here because totalSupply != 0;
 // since shares != 0 and totalSupply >= shares
 amount0 = FullMath.mulDiv(\_getBalance0(), shares, \_totalSupply);
 amount1 = FullMath.mulDiv(\_getBalance1(), shares, \_totalSupply);

 // Withdraw proportion of liquidity from Uniswap pool
 (uint256 t0FromPool, uint256 t1FromPool) = \_burnAndCollect(
 shares,
 \_totalSupply
 );

 // In addition to their share of vault-held tokens,
 // withdraw their share of uniswap-held tokens.
 amount0 = amount0.add(t0FromPool);
 amount1 = amount1.add(t1FromPool);

 require(amount0 >= amount0Min);
 require(amount1 >= amount1Min);

 // Push tokens to recipient
 \_transferTokens(to, amount0, amount1);

 emit Withdraw(msg.sender, to, shares, amount0, amount1);
 }

 /// @notice Deposits tokens in proportion to the vault's current holdings.
 /// @dev These tokens sit in the vault and are not used for liquidity on
 /// Uniswap until the next rebalance.
 /// function requirements:
 /// Either amount0Desired or amount1Desired must be > 0 or it will revert with 'CROSS'
 /// @param amount0Desired Max amount of token0 to deposit
 /// @param amount1Desired Max amount of token1 to deposit
 /// @param amount0Min Revert if resulting amount0Used is less than this
 /// @param amount1Min Revert if resulting amount1Used is less than this
 /// @param to Recipient of shares
 /// @return shares Number of shares minted
 /// @return amount0Used Amount of token0 deposited
 /// @return amount1Used Amount of token1 deposited
 function deposit(
 uint256 amount0Desired,
 uint256 amount1Desired,
 uint256 amount0Min,
 uint256 amount1Min,
 address to
 )
 public
 virtual
 whenNotPaused
 returns (uint256 shares, uint256 amount0Used, uint256 amount1Used)
 {
 // Update pool fees earned
 poke();

 // Calculate amounts proportional to vault's holdings
 (shares, amount0Used, amount1Used) = \_calcSharesAndAmounts(
 amount0Desired,
 amount1Desired
 );

 // Make sure deposit meets slippage requirements.
 // If amount0Used < amount0Min or amount1Used < amount1Min,
 // there has been too much slippage.
 require(shares > 0);
 // TotalSupply after deposit must not exceed max total supply
 require(totalSupply() + shares <= maxTotalSupply, "TOT");
 require(amount0Used >= amount0Min, "0");
 require(amount1Used >= amount1Min, "1");

 // Pull in tokens from sender
 if (amount0Used > 0) {
 token0.safeTransferFrom(msg.sender, address(this), amount0Used);
 }
 if (amount1Used > 0) {
 token1.safeTransferFrom(msg.sender, address(this), amount1Used);
 }

 // Mint shares to recipient
 \_mint(to, shares);
 emit Deposit(msg.sender, to, shares, amount0Used, amount1Used);
 }
// @notice 볼트의 보유량에 비례하여 토큰을 인출합니다. /// @param shares 발신자가 소각한 공유량 /// @param 금액0분 결과 `금액0`이 이보다 작으면 되돌립니다. /// @param amount1Min 결과 `금액1`이 이보다 작으면 되돌립니다. /// @param 토큰 수신자에게 전달합니다. /// @return amount0 수신자에게 전송된 토큰0의 금액 /// 반환 금액1 수신자에게 전송된 토큰1의 금액 함수 withdraw( uint256 주식, uint256 amount0Min, uint256 금액1분 주소 ) 외부 가상 반환 (uint256 금액0, uint256 금액1) { // 0보다 커야 합니다. // 출금할 주식은 0보다 커야 합니다. require(shares > 0); uint256 \_totalSupply = totalSupply(); // LPT 소각 \_burn(msg.sender, shares); // 미사용 잔액에 비례한 토큰 수량 계산 // LP 가치 = (유니스왑에 예치된 가치 + 예치되지 않은 볼트에 보관된 가치) / 총 LP 토큰. // 여기서는 미예치된 볼트에 보관된 가치를 계산합니다. // 총공급량 != 0이므로 여기에는 div(0) 세이프매쓰가 없습니다; // 주식 != 0이고 총공급 >= 주식이기 때문에 amount0 = FullMath.mulDiv(\_getBalance0(), shares, \_totalSupply); amount1 = FullMath.mulDiv(\_getBalance1(), shares, \_totalSupply); // 유니스왑 풀에서 유동성 비율을 인출합니다. (uint256 t0FromPool, uint256 t1FromPool) = \_burnAndCollect( 주식 \총공급 ); // 볼트 보유 토큰의 몫에 추가하여, // 유니스왑 보유 토큰의 몫을 인출합니다. 금액0 = 금액0.추가(t0FromPool); 금액1 = 금액1.추가(t1FromPool); require(amount0 >= amount0Min); require(amount1 >= amount1Min); // 수신자에게 토큰 푸시 \_transferTokens(to, amount0, amount1); emit Withdraw(msg.sender, to, shares, amount0, amount1); } /// @notice 볼트의 현재 보유량에 비례하여 토큰을 입금합니다. /// 이 토큰은 볼트에 보관되며 유동성 공급에 사용되지 않습니다. /// 다음 리밸런싱까지 유니스왑에 사용되지 않습니다. /// 기능 요구 사항: /// 금액0 원하는 금액 또는 금액1 원하는 금액이 0 이상이어야 하며, 그렇지 않으면 'CROSS'로 되돌아갑니다. /// @param amount0Desired 입금할 토큰0의 최대 금액 /// @param amount1Desired 입금할 토큰1의 최대 금액 /// @param amount0Min 결과 금액0사용량이 이보다 작으면 되돌립니다. /// @param amount1Min 결과 금액1사용량이 이보다 작으면 되돌립니다. /// @param to 수신자 공유 수취인 /// @return shares 발행된 주식 수 /// @return amount0사용된 금액 입금된 토큰0의 양 /// 반환 금액1사용된 토큰1 입금된 금액 함수 deposit( uint256 금액0원하는, uint256 금액1원합니다, uint256 금액0분, uint256 금액1분 주소 ) public 가상 whenNotPaused (uint256 주식, uint256 금액0사용, uint256 금액1사용)을 리턴합니다. { // 적립된 풀 수수료 업데이트 poke(); // 볼트 보유량에 비례한 금액을 계산합니다. (주식, 금액0사용, 금액1사용) = \_calcSharesAndAmounts( amount0Desired, amount1Desired ); // 입금이 슬리피지 요건을 충족하는지 확인합니다. // 금액0사용금액 < 금액0분 또는 금액1사용금액 < 금액1분인 경우, // 슬리피지가 너무 많이 발생했습니다. require(shares > 0); // 입금 후 총 공급량은 최대 총 공급량을 초과하지 않아야 합니다. require(totalSupply() + shares <= maxTotalSupply, "TOT"); require(amount0Used >= amount0Min, "0"); require(amount1Used >= amount1Min, "1"); // 발신자로부터 토큰 가져오기 if (amount0Used > 0) { token0.safeTransferFrom(msg.sender, address(this), amount0Used); } if (amount1Used > 0) { token1.safeTransferFrom(msg.발신자, 주소(this), 금액1사용); } // 수신자에게 주식 발행 \_mint(to, shares); emit Deposit(msg.sender, to, shares, amount0Used, amount1Used); }