Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/InvestProvider.Backend/Services/DefaultServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using InvestProvider.Backend.Services.Strapi;
using Microsoft.Extensions.DependencyInjection;
using poolz.finance.csharp.contracts.LockDealNFT;
using InvestProvider.Backend.Services.Handlers.Contexts;
using InvestProvider.Backend.Services.Web3.Eip712;
using poolz.finance.csharp.contracts.InvestProvider;
using InvestProvider.Backend.Services.Web3.Contracts;
Expand All @@ -29,6 +30,7 @@ public static class DefaultServiceProvider
.AddFluentValidation([Assembly.GetExecutingAssembly()])
.AddTransient(typeof(IPipelineBehavior<,>), typeof(ContextBuilderBehavior<,>))
.AddTransient(typeof(IRequestContextBuilder<>), typeof(PhaseContextBuilder<>))
.AddScoped<PhaseContext>()
.AddSingleton<IRpcProvider, ChainProvider>()
.AddSingleton<IChainProvider<ContractType>, ChainProvider>()
.AddSingleton<IStrapiClient, StrapiClient>()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
using MediatR;
using Newtonsoft.Json;
using Amazon.DynamoDBv2.DataModel;
using InvestProvider.Backend.Services.Strapi.Models;
using InvestProvider.Backend.Services.DynamoDb.Models;
using InvestProvider.Backend.Services.Handlers.Contexts;
using Net.Web3.EthereumWallet;
using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation;

namespace InvestProvider.Backend.Services.Handlers.AdminCreatePoolzBackId.Models;

public class AdminCreatePoolzBackIdRequest :
ProjectsInformation,
IRequest<AdminCreatePoolzBackIdResponse>,
IExistActivePhase,
IInvestPool
IPhaseRequest
{
[JsonRequired]
[DynamoDBIgnore]
public long ChainId { get; set; }
string IPhaseRequest.ProjectId => ProjectId;

[JsonIgnore]
[DynamoDBIgnore]
public bool FilterPhases => false;

[JsonIgnore]
[DynamoDBIgnore]
public ProjectInfo StrapiProjectInfo { get; set; } = null!;
public EthereumAddress? UserAddress => null;

[JsonIgnore]
[DynamoDBIgnore]
public string PhaseId => StrapiProjectInfo.CurrentPhase!.Id;
public string? WeiAmount => null;

[JsonIgnore]
[DynamoDBIgnore]
public string? PhaseId => Context.StrapiProjectInfo?.CurrentPhase?.Id;

[JsonIgnore]
[DynamoDBIgnore]
public PhaseContext Context { get; set; } = null!;

long? IPhaseRequest.ChainId => ChainId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public class AdminWriteAllocationHandler(IDynamoDBContext dynamoDb)

public async Task<AdminWriteAllocationResponse> Handle(AdminWriteAllocationRequest request, CancellationToken cancellationToken)
{
var toSave = request.Users.Select(x => new WhiteList(request.ProjectId, request.Phase.Start!.Value, x.UserAddress.ConvertToChecksumAddress(), x.Amount)).ToArray();
var ctx = request.Context;
var toSave = request.Users.Select(x => new WhiteList(request.ProjectId, ctx.Phase!.Start!.Value, x.UserAddress.ConvertToChecksumAddress(), x.Amount)).ToArray();
await Parallel.ForEachAsync(toSave.Chunk(BatchSize), new ParallelOptions
{
MaxDegreeOfParallelism = MaxParallel,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
using MediatR;
using Newtonsoft.Json;
using Poolz.Finance.CSharp.Strapi;
using InvestProvider.Backend.Services.Strapi.Models;
using InvestProvider.Backend.Services.Handlers.Contexts;
using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation;
using Net.Web3.EthereumWallet;

namespace InvestProvider.Backend.Services.Handlers.AdminWriteAllocation.Models;

public class AdminWriteAllocationRequest(string projectId, string phaseId, ICollection<UserWithAmount> users) :
IRequest<AdminWriteAllocationResponse>,
IValidatedDynamoDbProjectInfo,
IExistPhase,
IWhiteListPhase
IPhaseRequest
{
[JsonRequired]
public string ProjectId { get; } = projectId;
Expand All @@ -26,14 +23,14 @@ public class AdminWriteAllocationRequest(string projectId, string phaseId, IColl
public bool FilterPhases => false;

[JsonIgnore]
public ProjectInfo StrapiProjectInfo { get; set; } = null!;
public long? ChainId => Context.StrapiProjectInfo?.ChainId;

[JsonIgnore]
public long ChainId => StrapiProjectInfo.ChainId;
public EthereumAddress? UserAddress => null;

[JsonIgnore]
public ProjectsInformation DynamoDbProjectsInfo { get; set; } = null!;
public string? WeiAmount => null;

[JsonIgnore]
public ComponentPhaseStartEndAmount Phase { get; set; } = null!;
public PhaseContext Context { get; set; } = null!;
}
30 changes: 15 additions & 15 deletions src/InvestProvider.Backend/Services/Handlers/BasePhaseValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@
namespace InvestProvider.Backend.Services.Handlers;

public abstract class BasePhaseValidator<T> : AbstractValidator<T>
where T : IExistActivePhase
where T : IPhaseRequest
{
protected static bool HasCurrentPhase(IExistActivePhase model) =>
model.StrapiProjectInfo.CurrentPhase != null;
protected static bool HasCurrentPhase(IPhaseRequest model) =>
model.Context.StrapiProjectInfo?.CurrentPhase != null;

protected static bool HasProjectsInformation(IValidatedDynamoDbProjectInfo model) =>
model.DynamoDbProjectsInfo != null;
protected static bool HasProjectsInformation(IPhaseRequest model) =>
model.Context.DynamoDbProjectsInfo != null;

protected static bool SetPhase(IExistPhase model)
protected static bool SetPhase(IPhaseRequest model)
{
var phase = model.StrapiProjectInfo.Phases.FirstOrDefault(p => p.Id == model.PhaseId);
model.Phase = phase!;
var phase = model.Context.StrapiProjectInfo?.Phases.FirstOrDefault(p => p.Id == model.Context.PhaseId);
model.Context.Phase = phase!;
return phase != null;
}

protected static bool HasWhiteList(IWhiteListUser model) =>
model.WhiteList != null;
protected static bool HasWhiteList(IPhaseRequest model) =>
model.Context.WhiteList != null;

protected static IRuleBuilderOptions<TModel, TModel> WhiteListPhaseRules<TModel>(BasePhaseValidator<TModel> validator)
where TModel : IExistPhase, IValidatedDynamoDbProjectInfo
where TModel : IPhaseRequest
{
return validator.RuleFor(x => x)
.Cascade(CascadeMode.Stop)
Expand All @@ -35,10 +35,10 @@ protected static IRuleBuilderOptions<TModel, TModel> WhiteListPhaseRules<TModel>
.WithError(Error.NOT_FOUND_ACTIVE_PHASE, x => new { x.ProjectId })
.Must(m => SetPhase(m))
.WithError(Error.PHASE_IN_PROJECT_NOT_FOUND, x => new { x.ProjectId, x.PhaseId })
.Must(x => DateTime.UtcNow < x.Phase.Finish)
.WithError(Error.PHASE_FINISHED, x => new { EndTime = x.Phase.Finish, NowTime = DateTime.UtcNow })
.Must(x => x.Phase.MaxInvest == 0)
.Must(x => DateTime.UtcNow < x.Context.Phase!.Finish)
.WithError(Error.PHASE_FINISHED, x => new { EndTime = x.Context.Phase!.Finish, NowTime = DateTime.UtcNow })
.Must(x => x.Context.Phase!.MaxInvest == 0)
.WithError(Error.PHASE_IS_NOT_WHITELIST)
.When(x => x.StrapiProjectInfo.CurrentPhase!.MaxInvest == 0, ApplyConditionTo.CurrentValidator);
.When(x => x.Context.StrapiProjectInfo!.CurrentPhase!.MaxInvest == 0, ApplyConditionTo.CurrentValidator);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,42 @@
using InvestProvider.Backend.Services.DynamoDb.Models;
using InvestProvider.Backend.Services.Strapi;
using InvestProvider.Backend.Services.Handlers.Contexts;
using InvestProvider.Backend.Services.Handlers.AdminGetAllocation.Models;
using InvestProvider.Backend.Services.Handlers.MyUpcomingAllocation.Models;

namespace InvestProvider.Backend.Services.Handlers.ContextBuilders;

public class PhaseContextBuilder<T>(IStrapiClient strapi, IDynamoDBContext dynamoDb)
public class PhaseContextBuilder<T>(IStrapiClient strapi, IDynamoDBContext dynamoDb, PhaseContext context)
: IRequestContextBuilder<T>
where T : IExistActivePhase
{
public async Task BuildAsync(T request, CancellationToken cancellationToken)
{
request.StrapiProjectInfo = await strapi.ReceiveProjectInfoAsync(
request.ProjectId,
request.FilterPhases);
if (request is not IPhaseRequest phaseRequest)
return;

if (request is IValidatedDynamoDbProjectInfo validated)
phaseRequest.Context = context;
context.ProjectId = phaseRequest.ProjectId;
context.FilterPhases = phaseRequest.FilterPhases;
context.PhaseId = phaseRequest.PhaseId;
context.UserAddress = phaseRequest.UserAddress;
context.WeiAmount = phaseRequest.WeiAmount;

context.StrapiProjectInfo = await strapi.ReceiveProjectInfoAsync(
context.ProjectId,
context.FilterPhases);

if (phaseRequest is not AdminGetAllocationRequest && phaseRequest is not MyUpcomingAllocationRequest)
{
validated.DynamoDbProjectsInfo = await dynamoDb.LoadAsync<ProjectsInformation>(
request.ProjectId,
context.DynamoDbProjectsInfo = await dynamoDb.LoadAsync<ProjectsInformation>(
context.ProjectId,
cancellationToken);
}

if (request is IWhiteListUser whiteListUser && request.StrapiProjectInfo.CurrentPhase != null)
if (context.UserAddress != null && context.StrapiProjectInfo.CurrentPhase != null)

Check warning on line 36 in src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 36 in src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'left' in 'bool EthereumAddress.operator !=(EthereumAddress left, EthereumAddress right)'.

Check warning on line 36 in src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 36 in src/InvestProvider.Backend/Services/Handlers/ContextBuilders/PhaseContextBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'left' in 'bool EthereumAddress.operator !=(EthereumAddress left, EthereumAddress right)'.
{
whiteListUser.WhiteList = await dynamoDb.LoadAsync<WhiteList>(
WhiteList.CalculateHashId(request.ProjectId, request.StrapiProjectInfo.CurrentPhase.Start!.Value),
whiteListUser.UserAddress.Address,
context.WhiteList = await dynamoDb.LoadAsync<WhiteList>(
WhiteList.CalculateHashId(context.ProjectId, context.StrapiProjectInfo.CurrentPhase.Start!.Value),
context.UserAddress.Address,
cancellationToken);
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Poolz.Finance.CSharp.Strapi;
using InvestProvider.Backend.Services.Strapi.Models;
using ProjectsInformation = InvestProvider.Backend.Services.DynamoDb.Models.ProjectsInformation;
using InvestProvider.Backend.Services.DynamoDb.Models;
using InvestProvider.Backend.Services.Web3.Contracts.Models;
using Net.Web3.EthereumWallet;

namespace InvestProvider.Backend.Services.Handlers.Contexts;

public class PhaseContext
{
public required string ProjectId { get; set; }
public bool FilterPhases { get; set; } = true;

public string? PhaseId { get; set; }
public EthereumAddress? UserAddress { get; set; }
public string? WeiAmount { get; set; }

public ProjectInfo? StrapiProjectInfo { get; set; }
public ProjectsInformation? DynamoDbProjectsInfo { get; set; }
public ComponentPhaseStartEndAmount? Phase { get; set; }
public WhiteList? WhiteList { get; set; }
public UserInvestments[]? UserInvestments { get; set; }
public byte TokenDecimals { get; set; }
public decimal Amount { get; set; }
public decimal InvestedAmount { get; set; }
public long ChainId => StrapiProjectInfo?.ChainId ?? 0;
}

public interface IPhaseRequest
{
string ProjectId { get; }
bool FilterPhases { get; }
string? PhaseId { get; }
EthereumAddress? UserAddress { get; }
string? WeiAmount { get; }
long? ChainId { get; }
PhaseContext Context { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ ISignatureGenerator signatureGenerator
public Task<GenerateSignatureResponse> Handle(GenerateSignatureRequest request, CancellationToken cancellationToken) =>
Task.FromResult(new GenerateSignatureResponse(
GetSignature(chainProvider, signatureGenerator, request),
request.StrapiProjectInfo.CurrentPhase!.Finish!.Value,
request.DynamoDbProjectsInfo.PoolzBackId
request.Context.StrapiProjectInfo!.CurrentPhase!.Finish!.Value,
request.Context.DynamoDbProjectsInfo!.PoolzBackId
));

private static string GetSignature(
Expand All @@ -27,15 +27,15 @@ private static string GetSignature(
GenerateSignatureRequest request) =>
signatureGenerator.GenerateSignature(
new Eip712Domain(
chainId: request.StrapiProjectInfo.ChainId,
verifyingContract: chainProvider.ContractAddress(request.StrapiProjectInfo.ChainId, ContractType.InvestedProvider)
chainId: request.Context.StrapiProjectInfo!.ChainId,
verifyingContract: chainProvider.ContractAddress(request.Context.StrapiProjectInfo!.ChainId, ContractType.InvestedProvider)
),
new InvestMessage(
poolId: request.DynamoDbProjectsInfo.PoolzBackId,
userAddress: request.UserAddress,
amount: UnitConversion.Convert.ToWei(request.Amount, request.TokenDecimals),
validUntil: request.StrapiProjectInfo.CurrentPhase!.Finish!.Value,
nonce: request.UserInvestments.Length
poolId: request.Context.DynamoDbProjectsInfo!.PoolzBackId,
userAddress: request.Context.UserAddress!,
amount: UnitConversion.Convert.ToWei(request.Context.Amount, request.Context.TokenDecimals),
validUntil: request.Context.StrapiProjectInfo!.CurrentPhase!.Finish!.Value,
nonce: request.Context.UserInvestments!.Length
)
);
}
Loading
Loading